C# MVVM Model Graph Message Mediator or INotifyPropertyChanged? - c#

I am developing a C# MVVM WPF app and have problems to decide whether I should use the message mediator pattern or simple INotifyPropertyChanged for my UI 'live' Model change notifications. The problem in particular is that my model represents a graph with lots of 'live' objects that all have properties where different viewmodels will be interested in the changes at some point. I have about 3-5 viewmodels active that need notification of model changes. Some changes might be nested deep inside the models 'grandchildren'.
I tried to compare both messaging techniques, mediator pattern and INotifyPropertyChanged, and think that the mediator is better suited for change notifications between different modules/systems. My viewmodels definitely need the initial values of the model upon initialization and then change notifications afterwards. INotifyPropertyChanged seems to be the optimal choice in my case, but I am a bit skeptic, because I think lots of nameof(e.PropertyName) switch cases are not very elegant. Are there better alternatives for this problem?

As is typical for such cases, you could have both ways. You will obviously not be able to avoid using INotifyPropertyChanged because this is the WPF way of handling MVVM-based Data Binding, so all your view-models will be at least basic implementations of this interface.
I suspect that you might simply need both. I would not suggest using the INotifyPropertyChanged-based pattern inside your model. The reason this interface was created was to base the observer pattern on actual property names as strings. This was pretty much a "one-way street", as XAML, the typical "design" language supporting WPF, is parsed in a "stringly" manner, leaving few efficient alternatives. In my humble opinion, there is almost no reason that you would want to force notifications throughout your model to be as weakly-typed (stringly-typed, in fact) as this scenario, so I would suggest avoiding INotifyPropertyChanged if you have a relatively voluminous Domain Model.
Messaging would probably be the way to go, maintaining strong-typing with message type registrations and whatnot, unless you would like to consider other alternatives, such as simple C# events, or even combine both. While at it, try to stick and adhere to hierarchy and encapsulation as strongly as possible but also as weakly as practical*.
(*I mean, if some of your Domain objects reach multiple nesting levels, then, occasionally, it may be more practical to bypass hierarchy and let, for example, grand-grandchildren send messages of their own, instead of notifying their parents' parents through events, and letting these parents' parents then send the corresponding notification messages. In typical OOP programming, compromises are constantly weighted against practicality and time availability).

Related

Is grouping View Model properties into different categories a good practice?

I'm working on a WPF project using the MVVM pattern and I was wondering if I can improve the internal structure of my ViewModel by abstracting its exposed properties into separate classes.
It's common practice for VMs to contain lots of properties laying around in the same class: Some are used to retrieved user inputs, some are used to expose commands, others to expose the models, and probably some other properties for the view model's own business logic. Not to mention that these properties often have set and get bodies that adds some bulk to the package. This can quickly become messy inside a VM class and finding one's way there can become challenging.
As a way to solve this issue, I am exploring with my team the idea of grouping properties inside my VM into different categories. As a first approach, I chose to group them this way:
ViewData, UserInputs and Commands, each one represented by its own class. Then I referenced them as properties inside my VM class.
My intention is that these classes will only act as placeholders to free up the bloat in my VM and keep it clean and focused only on interaction logic for handling user events.
It's a simple refactoring, but I get the following pros:
Cleaner and readable VM.
Easier binding from the XAML because you know what the entry point is/should be.
Let me elaborate on the latter one: If I want to bind a text box to a property of my VM, I know the binding expression should start with Userinput.MyVMProperty. If I need to show a value from my VM, I know my binding's entry point is going to be ViewData.MyOtherVMProperty. Binding intellisense will also become better because when you know your entry point, the
suggestion list would be smaller and more focused. This also works the other way around: when reading through your XAML controls, any binding that starts with UserInput necessarily means it's a a control that should send data back to the VM.
The only cons I can find is that this will require creating extra classes for each VM, but I believe it's a fair price to pay for the benefits you get.
Take note that the grouping I suggested may not be the best, but I don't mind any other grouping as long as it solves the problem with bulky VMs.
So, has any one ever tried a similar pattern? Do you think this is a good idea/practice? What other good practices I can use to improve my VMs?
Bonus question: One developer in my team who seemed to agree with this idea, suggested to go the extra mile and consider the grouped classes as VM dependencies and that they need to be injected inside the VM. What do you think about this?
So for every ViewModel you need to create own inner classes for every group. You cannot use Interfaces because ViewModels have different properties and commands
Then did you considered that every "groupclass" must to "know" about other groups for ViewModel will work properly.
In my opinion Class should be solid logical structure with minimal outside dependency.
Based on the pros you trying to achieve I can suggest another approach without changing structure of the ViewModel classes
Readability can be achieved partly by #regions.
Or use Partial class for separating different groups in the different files,
while keeping them inside one logical structure
Intellisense can be improved by naming conveniences - using prefix based on group property belong to. For example UserInputMyName, ViewDataFullName or CommandDelete

Should a Presenter in the Model-View-Presenter pattern handle multiple 'UI' elements on a View?

I am implementing a Diagram/Flow-Chart type designer using a Model-View-Presenter (MVP) pattern in WPF.
I have often though of this pattern (and some of the others such as Passive View and MVVM) as high level architectures that fail to address some of the complexity involved in rich UIs (here come the SO trolls).
In my particular instance, I have a UI which resembles the following mockup:
I have made the choice to use Presenter objects for each element which requires presentation logic on the designer. This has left me with the following designers thus far.
DesignerPresenter
ControlPresenter
ControlOverlayPresenter
ConnectionPresenter
ConnectionPointPresenter
OverlayPresenter
The reason I have implemented each of these is because each of them needs to handle presentation logic and communicate its actions to the business/domain tier separately in order to avoid bloat (IMO).
The only other way I would see doing this is if there was one presenter that handles all this presentation logic which seems like it would get out of control very quickly.
My question(s) are as follows:
Is it common to see presenter provided for each UI element on the screen such as I am doing in order to allow for separation of the presentation logic?
Some of the presenters that are created are logically child presenters (The ControlPresenter is a child presenter of the DesignerPresenter) Is this normal?
Is this in alignment with another pattern that makes more sense?
I never used the MVP but I'm really comfortable with the MVVM pattern and if I replace the word Presenter with ViewModel the design fits with what I would really do.
It is completely normal that the DesignerPresenter has an ObservableCollection of ControlPresenter and that the ControlPresenter contains an ObservableCollection of ConnectionPresenter. The ConnectionPresenter will probably have two ConnectionPointPresenter as well.
The overall design seems ok but there are probably other similar architectures that would fit too. IMHO maybe there is too much separation. Makes sense to separate a connection and the connection points?

MVVM get/set vs OOP

By learning so much about the MVVM patterns I find it very useful and solves many problems we encounter on a daily.
But I dont understand how it goes along with OOP. OOP always dictates us to be encapsulated, to care about the hiding of fields (initialize them first in the constructor and no further access to set them) but if we define almost every model class with getter/setter properties it broke the rules of OOP.
So how does it goes along? Is it ok to define many get/set class in a real MVVM application?
Thanks,
Jacob
Hi I dont think it breaks the OOP concept. We expose the data members via public properties. So data hiding is there, user of the class does not know setting which property is going to change which data behind the scene. In the setter of the properties we can have validation logic and any chain of responsible methods/properties that can change the state of the class. So encapsulation and data hiding is there.
Thanks
There is no versus here, MVVM is an OOP design pattern.
Properties don't break OOP principles, it's an application of the encapsulation principle; i.e. control how an object data is acceded or modified.
Encapsulation don't tell us to avoid data modifications in objects, it tells us to be careful with it, to control it.
More infos on that here
As per the above answers, MVVM does not break OOP it embraces it. Ideally where you can, you should reduce the surface area of your software by limiting the read/write nature and encapsulating cohesive sets of properties into their own objects. This can lead you to having some parts of your model that are immutable. However, it is very difficult to follow a Immutable data model (DDD/Functional Programming concept) in MVVM if you have editing requirements.

Business Logic placement in WPF application

This might be a long list of questions but please bear with me. I started building LOB applications with WPF, PRISM, CODE FIRST and SQL CE, and after my first application (or attempt) I have many questions, so to begin with:
Where should business logic go, in the model or in a BLL layer just above the domain layer ?
Should view models receive references to repositories or should repositories be used only by the domain model objects ?
To put the second question in another way, what sort of objects should be given to view models ?
I use the same view model in display (in a data grid for example) and for editing in a form but that causes a lot of trouble, is there a better way to do this without code duplication ?
The biggest problem I have faced was that I always organized my view models in hierarchical relationships without allowing the children in the hierarchy to obtain references to their parents, and since the views bound to those children and invoked methods that caused the addition of objects to the repositories I couldn't find a way to notify the parents of the changes to the those repos. so the bound views could be updated, I have seen some people solve this using events but I don't like this solution and I would like to know if there is a better way to do it ?
Can anyone point to an example of building real life LOB applications using the technologies mentioned above, at least not examples that use VB .NET or WCF (I want local databases).
I'm developing a LOB app right now, with WPF, Entity Framework Code First and SQL CE 4.0 with a local database. I'm not using PRISM, but I'm using MEF as IoC with my own implementation.
So far, I recommend that you use the benefits of Code-First approach and implement as much business logic in your domain classes as possible. Also implement INPC in them. If you don't you'll end up having all your properties duplicated in your ViewModels, which is nonsense. There is no rule that says that the model should be dumb (although some people tend to think so), but a dumb model just makes the ViewModels more tedious to work with.
No clear recommendation here without knowing more of your project, but common sense: try to stick to best practices unless they start coming in your way. "Perfect" is often the enemy of "good".
Let the ViewModel get whatever they need (single model objects, collections, etc.) to serve your views. Often the simpler solution is easier to maintain in the long term.
I don't quite understand what you mean with this... I use my ViewModels several times if possible, but think that a ViewModel's function is to serve a View, if you are having trouble trying to get one VM to work for several Views, it's probable that you need to divide it into two different VM. Just gather all the common properties and methods in a base class and inherit from it as you need.
There are some loose-coupled ways for the VMs to communicate with each other. I'm using MVVM Light Messenger class for such things, but I understand that PRISM provides a similar functionality. It's not a sin to reference the parent from the child if you don't abuse it. I have a ViewModelBase<T> and the child have a reference for their parent pointing to the base class and specifying the T type, a good balance between hard and loose reference so far.
If someone points you to such an example, let me know! Actually, working with a local database should be simpler. In my case I'm using a singleton context (which a lot of people seem to loathe) but since this is a local app, with a single user and no threading complications a singleton context makes my life much easier. I'm still waiting to find a real good reason not to do so with this conditions.
PS: some people will probably downvote your question because... it is not ONE question, and it opens room for a lot of debate. If it gets closed, try the chat.
Hope this helps you, regards!

How should my model look like?

As I am further digging into MVVM and MVVM-light I recognized, that there is no MVVM-light provided base class for models.
But from my understanding, messaging and raising notifications could also happen in a model. At least in communication between models I would find that messaging would come in very handy.
So I just decided to derive my Model from ViewModelBase, even though some of the properties (like the design time ones) will be unused.
But the more I am looking at this, the more I think I have missed something. Is it considered "bad practice" to derive my Models from ViewModelBase?
And is it ok to use Messaging for Model communication?
Derive your view-model classes from whatever you like... MVVM-light offers the VieWModelBase to provide an implementation of ICleanUp - which is good for managing the life-cycle of ViewModel objects. My own choice has been to implement all scaffolding for Property Change notifications in a base class, then derive from that for model classes. About the only strong suggestions I have regarding model classes are:
Once size doesn't fit all. How you store your data may be different from how you interact with data, and ViewModel objects should be geared towards supporting interaction, not storage, and if you need to interact with the same data (Model) in two very different ways, then design two different ViewModels to support these different interactions.
Do use attributes (a la System.ComponentModel) to annotate the models. You can get a lot of your validation work done this way - and validation feedback is the responsibility of the presentation layer (View + ViewModel), not the problem domain (i.e. the Model).
Really good ViewModel classes are also usually stateless enough that they can be recycled/reused within a single user interaction, such that large data lists can be virtualized (WPF supports virtualization) to save RAM.
Remember DRY (Do Not Repeat Yourself), KISS (Keep It Simple, Stupid!) and YAGNI (You ain't gonna need it) - are the principles you should keep in mind above any academic design principles. I've litereally wasted weeks on a WPF app implementing academically perfect MVC/MVVM patterns, only to find that they detracted form the overall understandability of the finished solution. So... keep it simple! :)
I would take a look at the EventAggregator in the Composite Application Library. The answer in this post has a good description of it. Jeremy Miller's post goes into a bit more detail.

Categories

Resources