Avoid recursive generation of ViewModels in WPF - c#

I am trying to make a program which helps with combining persons to groups by matching their preferences.
But before I even come to the combining, I already have a problem with the viewmodels for this case.
Let's estimate the following classes:
public class Person
{
public string Name;
public List<Preference> PartnerPreferences;
}
public class Preference
{
public Person Partner;
public int Preference; //-1 does not want as partner / +1 does want as partner
}
I can now create the corresponding viewmodels VMPerson and VMPreference.
If I do it like I usually do, then the constructor of VMPerson will have somehting like this in it:
foreach (Preference pref in _person.PartnerPreferences)
{
PartnerPreferences.Add(new VMPreference(pref));
}
Where PartnerPfreferences is an Observablecollection<VMPreferences>
And in the VMPreference:
Person = new VMPerson(_preference.Person);
But when I want to create the viewmodels from even a simple model I will run into a loop generating infinite viewmodels.
Example:
The model has 2 persons, A and B. A wants B as his partner and B wants A as his partner.
Creating viewmodel for A
-> In VMPartner constructor, preferences of person A get wrapped in viewmodels
-> In VMPreference constructor, person B gets wrapped in viewmodel
-> In VMPartner constructor, preferences of person B get wrapped in viewmodels
-> In VMPreference constructor, person A gets wrapped in viewmodels
[And from here it will start all over again]
(Since the constructor of VMPreference can not know that person A already
has a viewmodel and he could stop here, setting the already existing
viewmodel in place)
The only solution I see is to make the VMPreference a VM with only string Name and int Preference. But this would disable many things like using Preferences.Add(new VMPreference(SelectedPerson)) and would also complicate the Viewmodel to Model conversion.
I am thankful for any tips and thoughts on how to solve this.

Where you say And from here it will start all over again, that is not necessarily true and it's entirely up to you how far it goes. The view models only wrap the data that you provide for them. Therefore, if you don't provide any preferences for the Person A that is actually set as the partner for Person B, then there will be no loop.
Furthermore, if you just make a rule that the Person objects set as the Partner property values don't have preferences, then you will equally avoid all loops. It's really a case of not all Person objects require all of their properties to be set.
You could just ensure that all Person objects on the main level are fully populated, but the ones referred to from the Partner properties are not and just have whichever property values that you require.

Do you need the preference to relate to the the full person? It looks as though you might get away with having a third simpler person reference class which doesn't include the preferences collection. Unless of course you want a mass of interlinked preferences to traverse. Your current person class could even extend it.
Another idea, as found in entity framework which deals with the same issue in the form of navigation properties, is to make the collection lazy load from your data source. That way, the person property in your preference object is only assigned when a get is called.

Related

Generate a unique ID to a body property of an object that's CONSISTENT through runtime and presents no overhead to the developer on implementation

This problem is a bit hard to expose via the title so I hope the following clarifies my intentions a bit.
Suppose you have the following data classes:
class abstract Employee {
string ID;
}
class FullTimeEmployee : Employee {
string schedule;
}
class PartTimeEmployee : Employee{
string schedulePartTime;
}
class WheelsSpecialist : Employee{ }
class InteriorsSpecialist : Employee{ }
class Workshop {
WheelsSpecialist wheely_guy;
InteriorsSpecialist interiors_guy;
}
Now, suppose that I instantiate my workshop as follows:
var Workshop = new Workshop{
wheely_guy = new PartTimeEmployee(),
interiors_guy = new FullTimeEmployee();
}
Please assume that the structure / inheritance and instantiations here provided are immutable.
What I'd like is to generate an ID set on Employee.ID that survives the runtime and is consist and independent from class properties / developer implementation.
Understand also that: The path of each object property in the workshop instantiation is guaranteed to be UNIQUE.
As so, a good ID for the WheelsSpecialist in Workshop.wheely_guy would be "Workshop.wheely_guy". (for example) because no path will ever be the same when I'm instantiating the workshop.
When I access the object "Workshop.wheely_guy.ID" I'd like to have "Workshop.wheely_guy" there or something analogous.
I imagine something like this would work (non valid C#, logic intact):
class PartTimeEmployee {
//instantiationPath is for example, "Workshop.wheely_guy"
onCreate(string instantiationPath){
this.ID = instantionPath;
}
}
I've tried this with StackTrace and whatnot, but couldn't find a way of doing it right.
Whether this instantiationPath method is used or not, the solution requires that:
I get to keep my structure as is in the example EXCEPT for properties. Those can change.
When I want to add a new dimension to my workshop variable I CAN'T, as a developer, be responsible for awarding a class it's own unique property.
As so, doing something like "this.ID = wheels" manually is not an option (also, depending this ID on properties that the developer must implement is also not viable).
Can this be done some way that meets my demands?
Thank you!
The provided code does not compile, and the object design/inheritance used seems a bit off. You probably want to work on the abstractions themselves. But that is not what you asked (mainly). It's kind of hard to figure out what exactly you asked, but I will do my best to answer what I think you asked (mostly):
"I want a field of an object instance to contain an automatically calculated navigation path by which it is accessible in some collection or composite object unrelated to the object itself" -> while close to impossible in C#, this might be entirely/easily possible in other languages. Still, the concept itself seems a little off.
The premise here is that the Employee object does not and should not know about the Workshop object Think about part-time employees trying to work separate shifts in separate workshops at the same time, and other possible changes in the business logic regarding Employees and Workshops.
Let's walk through some of the possibilities, ordered by viability:
Doing some magic at constructor/instantiation time in the abstract constructor code (Stack Frame walking, callerMember tricks, Reflection?, AST parsing?)
At instantiation, in a constructor, the stack trace does not contain information about which property/field it is about to be assigned to (if at all for that matter, it might just need to be instantiated, not assigned to anything). So there is no way to set such an id at constructor time.
Doing some magic in the Id property getter
There is no way to pass in parameters to a property getter, so we run into the same type of problem as with option 1: the stack trace contains no useful information by the time the getter is accessed.
Make the Employee object know about Workshop
No, just no.
Some weird runtime/weaving magic to "calculate" these paths when they are accessed?
Maybe, but how much effort to put in and to what purpose?
Expression parsing in a separate method:
//Left out the non-compiling code.
public static void Main(string[] args)
{
var Workshop = new Workshop
{
WheelsGuy = new PartTimeEmployee(),
InteriorsGuy = new FullTimeEmployee()
};
Console.WriteLine(GetObjectAccessPath((_) => Workshop.WheelsGuy));
}
public static string GetObjectAccessPath(Expression<Func<Workshop, Employee>> member)
{
string body = member.Body.Reduce().ToString();
// the line below might take some tweaking depending on your needs
return body.Substring(body.IndexOf($"{nameof(Workshop)}"));
}
// Output: Workshop.WheelsGuy
Use Reflection in a separate method to "get" a list of properties that are of any type derived from Employee and based on that Generate a list of ids with something like properties.Select(p => $"Workshop_{p.Name}");
Most viable: Re-design the object model:
(This is my opinion, and the requirements of your project might be different. Even if I am speculating here, the same principles presented here would apply in many other ways).
Extract more abstractions, like Position, Role, and Schedule. Part-time would be a schedule. Wheels guy would be a role. Position would be "an employee that fulfills the role of wheels guy at a workshop." There might be more examples (pay by hour/week/month, tax exemption, etc.).
As a rule, holding too many concerns in one class is a code smell and will get you in trouble quick. You can choose to carve up the classes however you want, but for what you "seem" to want, this part is important: have a class that represents the relationship between employee and workshop.
For example, instead of the Workshop holding instances of Employees: the Position class would hold/know about an Employee, his Role, his Schedule, and the Workshop he works at. The Position's Id could then easily be Id => $"Workshop_{Role}"; or Id => $"{WorkShop}_{Role}", etc. As a bonus, you get the design bonus of the Workshop being free from knowing which types of employees it might hold.
In general, I'd suggest you look into SOLID principles, it's an eye opener.

How should aggregate expose info from child entity?

[ Follow up from this question Should entity have methods and if so how to prevent them from being called outside aggregate ]
I am trying to understand in full details how aggregate root exposes data from its child entities to outer world; in particular, at least repository will need that info in order to be able to save it.
So, for the sake of the argument, lets consider these rules:
Person have a few channels of communication: phone, email, facebook account (might as well be a collection of each of those but for simplicity lets say its just one of each).
Person can choose to make any of those channels public so that other Persons can contact him or make any of those private so that he can't be pinged through that particular channel.
Person can choose global setting of not being contacted at all. In that case, its forbidden to switch any of the phone, email, facebook to public.
[ Note: the model i'll show now might not be the best one but lets leave remodeling aside for now and focus on exposing child entity infos ]
lets say we have aggregate root Person (c# code), only with example for Phone entity as others are the same logic:
class Person {
...
private Phone Phone { get; set;}
public bool WantsToBeContactedAtAll { get; }
public void ExposePhoneNumberPublic() {
if(!this.WantsToBeContactedAtAll)
throw new SomeError("Not allowed.");
this.Phone.PublishPhoneNumber(true);
}
public void HidePhoneNumber() {
this.Phone.PublishPhoneNumber(false)
}
}
class Phone {
//this is identifier
public readonly string PhoneNumber { get; private set; }
public string Description { get; private set; }
public boolean ShouldBePublished { get; private set; }
public Phone(string phoneNumber, string description, bool shouldBePublished) {
//set values
}
public void PublishPhoneNumber(bool preference){
this.ShouldBePublished = preference;
}
So, what we want to prevent is someone doing:
Person Adam = new Person(...);
Adam.Phone.PublishPhoneNumber(true);
But now, we still need info from Adam.Phone if for nothing else, then for the repository to access it when saving aggregate:
_personRepository.Add(Adam);
Questions:
How to expose Person.Phone info?
Should we expose some copy of the Phone property as a struct (value object)?
Have Phone as private type within Person aggregate and expose another PhoneReadOnly type what would be just a class with properties and getters.
Another way of asking those all question is: how can at least repository read Person.Phone information that it needs in order to be able to save Person?
Please treat me as a complete idiot and explain in details.
Thanks
How shoud aggregate expose info from child entity?
In a way that doesn't allow the caller to change the state of the aggregate.
Pass a primitive value
Pass a reference to an immutable object
Pass a copy of an object
Copies of information are fine, because you can't change my state by changing your copy of my data. References to immutable objects are fine, because you can't change them at all, therefore you can't change my state. But giving you a reference to my mutable state increases the odds of a programmer error.
Let's consider the repository example for a moment -- repositories, remember, are used to give the application the illusion that all of the aggregates are just members of some vast, in memory collection. To support this illusion, the repository needs two functions -- one that takes a representation from our stable data store and creates from it the domain model entities that make up the aggregate, and another that takes the aggregate and constructs from it the representation to put in the data store.
Let's pretend that we had some really naive aggregate that was just an array of integers
class Aggregate {
int [] State;
}
And then we imagine the functions that a repository might need to load and store this aggregate
Aggregate a = Aggregate.from(state)
int [] state = a.state
Now, what happens if we try to cheat?
int [] state = a.state;
state[0] = 12345;
Did a change? Since we want the domain model to be the authority for the state of the world, the answer had better be "no". Which in turn means that the aggregate doesn't yield a reference to its own array, but instead a copy of that array.
The same principle applies if we think about an aggregate with an array of child entities.
class Aggregate {
Child [] children;
}
So what does this aggregate yield? Not it's own array, because that would allow the client to change the aggregate by replacing a Child. But it can't just copy the array either, because we could call methods on one of the child array elements to change itself, which would indirectly change the state of the aggregate.
So we don't return an array of children, we return an array of descriptions of children. It's a sort of "deep copy". The descriptions contain copies of data, but no references -- nothing that links back to the internals of the entity itself -- and so it is safe to yield the description to a caller, who can do what they like with it (including sticking the description into a document store for later recovery).
I tend to think that making your child entities (immutable) value objects simplifies this issue a lot.
A rule of thumb is that you never modify a value object, you replace it. Unlike controlling what people do with the inside of your sub-entities, assigning a value to a direct property of the AR is something you can easily restrict from the root. You can just mark the setter as private and only allow changing it by going through the adequate AR method:
class Person {
public Phone Phone { get; private set; }
public void ExposePhoneNumberPublic() {
if(!this.WantsToBeContactedAtAll)
throw new SomeError("Not allowed.");
Phone = new Phone(Phone.Number, Phone.Description, shouldBePublished: true);
}
}
Note that the part where you take the existing Phone and new up a slightly different one could be done more elegantly - see the "with" keyword here.
Another way of asking those all question is: how can at least
repository read Person.Phone information that it needs in order to be
able to save Person?
I believe that's actually a totally different question. Usually, reading is not the hardest part - if you want any client code to be able to read the Phone, there's no reason that a Repository won't. Writing can be more tricky, as a well-encapsulated aggregate root doesn't necessarily let you change it like that. With ORMs, making the setters protected will work most of the time. An alternative is to use internal with InternalsVisibleTo the concrete repository's assembly, or work with a fully mutable backing state object.

Moving to a specific item in CollectionViewSource?

I'm new at WPF and I'm trying to use MVVM. I'm using CollectionViewSource in my view-model against a SQL database using Entity Framework.
So let's say I have this class:
public class People
{
public int Id { get; set; }
public string name { get; set; }
}
And lets say this is what I have in the database:
ID: Name:
Bugs Bunny
Mick Jagger
Mickey Mouse
Donald Duck
Goofy
Elmer Fudd
Daffy Duck
Porky Pig
Now using CollectionViewSource.View, I know how to use the methods MoveCurrentToNext(), MoveCurrentToPrevious(), etc. and that works fine, but I need to move to a specific name, for example Donald Duck. So if I do this:
dbContext.Peoples.Find(4);
Or if I do this
dbContext.Peoples.Where(p => p.Name == "Donald Duck").FirstOrDefault();
That will get me the right object from the database using Entity Framework. However, if I do this:
CollectionViewSource.View.MoveCurrentTo(dbContext.Peoples.Find(4));
It will not move, and CollectionViewSource.View.CurrentItem is null.
So then how would someone move to the correct item?
I guess this is because the reference that you get when calling dbContext.Peoples.Find(4) is not the same as the one you have in your CollectionView source collection.
The CollectionViewSource.View.MoveCurrentTo (an others 'MoveTo' methods of the collectionView) requires an argument that is the same reference as the one in your source collection.
Then, if your dbContext methods to retreive an object returns a new instance or an instance different than the one in your CollectionView, this won't work.
So either use an intermediate collection as the source of the collection view to keep a unique reference to the objects (and update these references when the object in in data access context change) or try to implement equality members in your People class (never tried the later solution but should work).
Also, try to add in your question some complete piece of code rather than code fragments about which we can't realy see exactly where is the problem.

Add editing to MVVM in a hierarchical data structure

This question is a follow-up of this older one, and it's more of a confirmation than an open question.
My ViewModel instance has a private instance of the Model, _modelInst.
The ViewModel has exclusive access to the Model's data during editing (so the Model doesn't need to implement INotifyPropertyChanged).
Now there are three ways I came up with how to edit the Model data from the View:
Getting/setting directly on the Model instance
e.g. for simple value fields
return _modelInst.fieldname;
_modelInst.fieldname = value;
This one's easy to implement...
Creating a ViewModel instance and operating on the parent's data structure
e.g. for more complex object types like structs:
Creating a new ViewModel for that type.
The ViewModel knows the parent and its fieldname.
displaying that in a ContentControl+DataTemplate
getting / setting:
via methods of the parent with the fieldname as parameter,
overwriting the whole original object even if only one field is changed
This means creating a new interface (with update routines working on _modelInst), implemented by the parent, for each of these structures.
Creating ViewModel instances with no direct knowledge of the parent's data structure
e.g. for (lists of) classes within parent classes
Creating a new ViewModel for each class
Sending update instructions to the parent via
commands
messages
reflection (parent knows which child called the function
by comparing the instance to all stored children)
All of these are a big mess implementing, creating functions for
every field of the model that is editable.
Which means pretty much all fields of the model...
(4.) One could create a generic ViewModel which works via reflection alone, where each
subobject knows its parent and its fieldname (+index, if in a list).
Only the root's logic would then interfere with the model.
But that solution would also require a means to store the path to a field within _modelInst.
Is there any other (more simple) way to achieve this?
Did I misunderstand the principles of MVVM (again)?
Is MVVM suited for manipulation of large hierarchical data structures?
Hopefully these resources will help; they helped me quite a bit as I learned MVVM and how to approach representing object graphs/hierarchies with view models:
Editable Object Adapter
Editable Collection Adapter
MicroModels
This is an excellent question for which I do not feel there is a good answer that comes stock with the MVC pattern.
ViewModels work great when the model they map to has no children.
But when the model has children, as in
Customer
-->Order
-->Country
(imagining Country were a child object of Customer) the design pattern kind of breaks down.
The best thing I've found is to use inheritance and selectively expose
only those children for which you need viewmodel logic. Otherwise, just access
the model's properties of the view that will come in via inheritance.
public class CustomerView : Customer //inherits from Customer (model)
{
public CustomerView(Customer customer)
{
this.FirstName = customer.FirstName
//etc..
//Only if you need it, that is if you have some display-specific
//logic relating to country for a given view, you create
//a CountryView class that inherits from Country and gets populated
//by an instance of it as well
this.CountryView = new CountryView(customer.Country)
}
public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.
public string DisplayColor
{
if(base.FirstName == "Joe")
{
return "red";
}
return "";
}
}
This gets messy when dealing with grandchildren. If anyone has a better solution, I would love to hear it.
Thanks

C# CSLA business object dilemma: read-only vs read/write

I'm part of a team tasked to revamping our old VB6 UI/COBOL database application to modern times. Before I was hired, the decision was made (largely on sales, I'm sure) to redo the UI before the database. So, now we're using WPF and MVVM to great effect, it's been amazing so far, especially using CSLA as our Model layer.
However, because our development is side-by-side with the next version of the old product, we're constrained a bit. We can't make any changes (or minimal changes) to the calls made to the COBOL database. This has been fine so far, albeit pining back to the glory days of SQL Server if you can believe it.
Where I've hit a particularly nasty roadblock regarding our BO design is in dealing with "light" business objects returned in lists and their "full" counterparts. Let me try and construct an example:
Let's say we have a person object in the DB with a bunch of fields. When we do a search on that table, we don't return all the fields, so we populate our lite object with these. These fields may or may not be a subset of the full person. We may have done a join or two to retrieve some other information specific to the search. But, if we want to edit our person object, we have to make another call to get the full version to populate the UI. This leaves us with two objects and attempting to juggle their state in 1 VM, all the while trying to keep the person list in sync on whatever parent object it sits after delete, edit, and add. Originally, I made our lite person object derive from ReadOnlyBase<>. But now that I'm dealing with the same list behavior you'd have with a list of full BOs except with half full, half lite, I'm thinking I should've just made both the lite and full versions derive from BusinessBase<> and simply made the lite version setter properties private.
Has anyone else out there come across and found a solution for this? After sleeping on it, I've come up with this potential solution. What if we wrap the full and lite version of our BO in another BO, like this:
public class PersonFull : BusinessBase<PersonFull>
{
...
}
public class PersonLite : BusinessBase<PersonLite>
{
...
}
public class Person : BusinessBase<Person>
{
public PersonFull PersonFull;
public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}
Obviously everything would be CSLA registered properties and such, but for the sake of brevity they're fields there. In this case Person and PersonList would hold all the factory methods. After a search operation PersonList would be populated by Person objects whose PersonLite members were all populated and the PersonFull objects were all null. If we needed to get the full version, we simply tell the Person object to do so, and now we have our PersonFull object so we can populate the edit UI. If the Person object is to be deleted, we can easily do this with the CSLA delete procedures in place, while still maintaining the integrity of our lists across all the VMs that are listening to it.
So, I hope this made sense to everyone, and if anyone has a different solution they've successfully employed or criticism of this one, by all means!
Thanks!
(Reposted from: http://forums.lhotka.net/forums/thread/35576.aspx)
public class PersonLite : ReadOnlyBase<PersonLite>
{
public void Update(PersonFull person) { }
}
public class PersonFull : BusinessBase<PersonFull>
{
// blah blah
}
I would update the "lite" object with the changes made to the "full" object, and leave it as ReadOnlyBase. It's important to remember that the "ReadOnly" in ReadOnlyBase means an object that is only read from the database, and never saved to it. A less elegant, but more accurate name would be NotSavableBase, because such objects lack the DataPortal_XYZ machinery for anything but fetches. For obvious reasons, such objects usually have immutable properties, but they don't have to. ReadOnlyBase derives from Core.BindableBase and implements INotifyPropertyChanged, so changing the values of its properties will work just fine with binding.
When you save your "full" object, you pass the newly saved instance to the Update(PersonFull) method of the instance that sits in your list, and update the properties of the "lite" object from the "full" object.
I've used this technique many times and it works just fine.
If you look over Rocky's examples that come with the CSLA framework, you'll notice that he always separates the read only objects from the read/write objects. I think this is done for good reason, because the behaviors are going to be drastically different. Read only objects will be more performance based, their validation will be very different, and usually have less information altogether. The read/write objects will not be as perfomance based and rely heavily on validation, authorization, etc.
However, that leaves you with the dilemma you currently find yourself in. What I would do is overload the constructor of each class so you can pass them between each other and "copy" what you need out of each other.
Something like this:
public class PersonLite : BusinessBase<PersonLite>
{
public PersonLite(PersonFull fullPerson)
{
//copy from fullPerson's properties or whatever
}
}
public class PersonFull : BusinessBase<PersonFull>
{
public PersonFull(PersonLite litePerson)
{
//copy from litePerson's properties or whatever
}
}
You could do this with a factory pattern as well, which is Rocky's preference I believe.

Categories