After fighting for a while with maintaining model-viewmodel relationships (eg. creating vm instances for each instance of model) I've got some ideas that might be quite controversial, but I'm curious of opinions.
What if VM class was made to maintain a static list of containers for model instances.
Those could(or even should) be weak references so whenever model class instance is out of scope its viewmodel is automatically disposed. Another option would be to reuse vm instances.
Another idea that would work well with the first one might be creating an implicit cast operator from model to viewmodel class. I would always get the same instance of vm whenever casting from model instance.
What do you think about it ? Is this a hard violation of rules and MVVM pattern?
//edit
I should probably provide also what was the motive behind this: in my app I have multiple places where I use one of my model classes and need corresponding vm references. In every such place I need to observe a collection and react to changes -creating or removing vm instances. This is basically the same code that is repeated in many places => I thought of creating only one place to do that (implicit cast is just a candy it's not required to solve the real problem). Or maybe instead of static lists I should create a manager that would handle view model instance creation for all my classes?
First of all, I am not to sure whether your ideas violate the MVVM pattern. In my opinion it is not that important to fullfill patterns in every case. A pattern in my eyes suggests strategies to solve problems. In most cases it is not worth following a pattern 100% by all means. If there is a pragmatic solution you should rather use this one. Of course this should be solutions that lead you to your aims, e.g. unit testable, separation of UI and applicatiopn logic and so on.
Anyway, when I was reading your article the first time I thought implementing a cast operator is good idea. But if I am not wrong, you need to reference the view model in your model. I always try to avoid that to maximize re-use opportunities. But I think having such a reference does not violate the pattern. Maybe someone else can tell more about that.
For me your manager idea is the best way. I use a similar way to create view models. It depends on how many view model you need to create, but you should rather create new view models than re-using existing ones. Somewhere I read that view models should be some kind of state machine to the view. Following this idea, you never know in what state the view model is when you re-use it. So the preferred way is to create a new view model.
Just some thoughts! Maybe there are some other ideas...
Related
Almost every MVVM example I've come across has both the Model and ViewModel implementing INotifyPropertyChanged.
Other sources (ones which focus on domain modeling) seem to suggest that Models should be incredibly plain (something to do with separation of concerns?) with essentially no references to anything. Unfortunately, those sources don't use MVVM.
I'm trying to reconcile the two.
-I'm relatively new to programming and completely new to design patterns and the like so please try to go easy on me.
Edit: Let me rephrase my question. Given that the answer to the above seems to be "sometimes one and sometimes the other," WHEN should you do one and and when should you do the other. Also, how would each be implemented?
(That isn't answered in the other post. It just has them arguing with each other).
Models have to implement INotifyPropertyChanged to inform the view model that they have changed. If the model doesn't implement INotifyPropertyChanged (or another equivalent interface), then the view model is stuck using polling or other similarly inefficient methods to detect changes in the model state.
This MSDN page may be useful reading to further understand the roles of the various components that make up the MVVM pattern.
I have no idea if this is a best practice, but I have my ViewModel set up so that it is the only active entity. The Model is only directly changed when created by reading from a database (and then loaded into a ViewModel), or before saving to database (extracting from ViewModel, modifying Model properties that only matter to the database, like foreign keys).
If for some reason you desire being able to have multiple ViewModels connected to the same Model or have a need to change a Model from under a ViewModel, then you'd have a good reason to implement INotifyPropertyChanged on the Model.
I'm a relative amateur, so take what I say with a grain of salt. But this is what I've been gathering, and enforcing this separation has, I think, made my code cleaner and easier to understand and debug. So for my own projects, I'm going to try avoiding implementing INotifyPropertyChanged on my Models if I can avoid it.
I have an MVC ASP.NET project and I currently use a static ViewModelHelper class which has several methods (1 for each view model) that take in certain parameters and model objects and generate the view model objects for me to return to my views from my controllers. They are currently all static and the class as a whole is stateless, I just use it when I want to instantiate an instance of the view models because some of the data requires rather complex logic.
Would these methods be better off as constructors in the View Model classes? My understanding was it is better not to have any logic in the View Models, but I could be wrong. Or is there perhaps a design pattern I should be using here to help me create these View Models?
It's a question of your project's architecture and design how your ViewModels should look like and where/how they should be initialized. It seems that right now your ViewModels are DTOs and you initialize them with a factory approach. That is fine, but I'd suggest to actually embrace the abstract factory pattern then and make sure that the factory implementation doesn't get overloaded with unrelated responsibilities. That is an inherit problem of "utility" classes that should make every developer wary.
On the other hand, view-related initialization logic, e.g. populating select lists, can very well be located in the ViewModels themselves. In that case you should be wary of duplication.
Another possible approach would be to utilize a builder pattern.
Either way can be a clean solution if you use it exclusively and not mix and match. And as long as you keep it clean, of course. ;)
Without having seen that rather complex logic, I'd suggest you check why the initialization logic is that complex to begin with, though. And if it really has to be. Maybe some business logic snuck in there?
Your ViewModels should be just DTOs, classes with properties only. No logic. Put logic in other classes (services or full business logic, depends) and have them populate the ViewModel.
I'm aware to the fact that this answer seems very short relative to the substantial design consideration, but that's the core of it. For reasoning etc. please have a look at some full-fledge ASP.NET MVC solutions that demonstrate it, like https://prodinner.codeplex.com/.
I'm refactoring and redesigning the domain objects of my application which uses MVVM to some extent. Is there anything that speaks against making all Domain objects (POCOs) inherit from INotifyPropertyChanged, so anyone can observe the objects as they wish.
In combination with https://stackoverflow.com/a/1316566/448357 this does not even have to be very ugly.
On the other hand, what about polluting my domain object with stuff that might not be required at all, because there will be a separate View-Model anyway? Margabit points out: UI Model != Domain Model
IMO, Domain objects shouldn't implement INotifyPropertyChanged. The one who should be implementing it is your ViewModel.
The reasons for that is:
You would probably mostly need to raise a PropertyChanged event inside your viewmodel which holds your POCOs
You would be implementing it only once.
If your POCO wants to raise an event and notify that something has occured inside it, im not sure PropertyChanged would be the most meaningful event to raise.
I think it depends a little bit on the scope of the project: if this is a small project, where Domainmodels are also used as UI-mmodels, sure go ahed an do so if you like.
But if you frequently NEED UI-models, e.g. because there are a lot of properties / methods which are not part of your domain model, don't bother - you create overhead for little or no reason.
When do you need a UI-model? My rule of thumb: If you are introducing a property with an[NotMapped] (Entity Framework) Attribute, go ahead and make a UI-model with this property.
Alsoif there is a chance that parts of this project are used in another context( Webapp, phone etc. pp) , I would advise against it- you will need UI models anyway.
To avoid to insert code in your classes you can make a transparent proxy.
You can use Castle
http://www.castleproject.org/dynamicproxy/index.html
The only limitation is that you have to create instances of your classes via factory.
You could also use System.Runtime.Remoting.Proxies.RealProxy class but your base class must derive from MarshalByRef (is still POCO? :) ).
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=IT-IT&k=k(SYSTEM.RUNTIME.REMOTING.PROXIES.REALPROXY)%3bk(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22)%3bk(DevLang-CSHARP)&rd=true
I have one ViewModel for enums handling (few entities in Entity Framework).
1) Philosophically, is it a good practice to use a SINGLETON PATTERN for this ViewModel, because it's widespread over all application and it's used on many places.
2) Isn't it a problem for ViewModel (and associated ObjectContext) to live for very long time?
Thank you!
This should probably be broken up into two separate questions, but I'll take a stab at both:
No. There's no reason a ViewModel should be a Singleton. You actually WANT multiple instances (since each is going to vary) rather than a single instance that lives for the run of the application. Just because an object is widespread and is used frequently doesn't make it a good candidate for a singleton...it just means that it's a good object.
ViewModels should not have a very long lifetime (another reason you don't want a singleton). In MVVM, the lifespan of a given ViewModel would be as long as the user has the window open and finishes their changes.
Having a singleton ViewModel is entirely valid in specific cases. One example I have used multiple times is a SettingsViewModel. Which needs to be accessed globally by multiple systems within the app. My Settings Model on creation loads up settings from a file, the ViewModel allows me to bind to modify those settings. The singleton allows me to globally access those settings where I need instead of passing them around as parameters.
Entirely valid, in this case.
1) don't do it. see MVVM ViewModels Singleton
2) I don't think it's a good idea to have a viewmodel coupled to an object context. It should be just a viewmodel, providing data to a view; but not tightly coupled to any data persistance technology. Instead, inject services that take care of this, so you can mock them.
The objects only live on the stack as long as the garbage collectors deems them to be necessary. Philosophically no it is not a good idea to use Singleton as it breaks encapsulation. See article: Singleton antipattern
As Justin mentioned, it seems unlikely you'll need your ViewModels to follow the Singleton Pattern. However, as you mentioned, View Models are used throughout the system. Consider pulling common functionality into base classes (if you like inheritance) and/or pull reusable components into objects to take advantage of composition.
An easy way to start this is all the lines of Josh Smith's ViewModelBase and a typical ViewModel's usage of INotifyPropertyChanged.
Give that code a look here: http://mvvmfoundation.codeplex.com/
I am building an application that is based on MVVM-Light. I am in the need of creating multiple instances of the same View, and each one should bind to its own ViewModel.
The default ViewModelLocator implements ViewModels as singletons, therefore different instances of the same View will bind to the same ViewModel.
I could create the ViewModel in the VMLocator as a non-static object (as simple as returning new VM()...), but that would only partially help me.
In fact, I still need to keep track of the opened windows. Nevertheless, each window might open several other windows (of a different kind, though). In this situation I might need to execute some operation on the parent View and all its children. For example before closing the View P, I might want to close all its children (view C1, view C2, etc.).
Hence, is there any simple and easy way to achieve this? Or is there any best practice you would advice me to follow?
Thanks in advance for your precious help.
Cheers,
Gianluca.
There is no obligation to store the ViewModels as singletons in the ViewModelLocator, but it certainly makes them easier to find if the view is a singleton too. Obviously, if you have multiple instances of the same View class, you will have multiple instances of the same ViewModel class, and it cannot be a singleton anymore.
To keep track of the multiple instances of the ViewModel, you can implement a dictionary in the ViewModelLocator that looks up for a ViewModel according to a key. The key can be a unique ID for the view, for example. Once you get hold of the view, retrieve its key and then retrieve the viewmodel from the locator.
Update: Often you don't even need to track multiple viewmodels. For instance, you can have the Messenger class send a message to all instances of a given viewmodel class using the Send overload. So before implementing a dictionary to keep track of the VMs, ask yourself if you really need it! ;)
Hope that helps,
Laurent
I used the naming system of the unity container.
See "How to distinguish multiple view/view model pairs using unity container".
I had a problem posted and solved in this SO question. It turned out to be very much related to Mr Bugnion's answer here (which helped me tremendously, thank you!)
What I've found is you don't need to store the view-model property in ViewModelLocator at all. Just use ServiceLocator to create an instance with a key, and in your "Dialog Service", pass the key to ShowDialog<T>(string key = null).
Also, as mentioned in this thread already, use method Messenger.Default.Send and remember to call viewModel.Cleanup() afterwards to unregister the view-model from Messenger, thereby preventing phantom view-models from trying to process future messages sent to all instances of the view-model class type.