MVVM - Handling backing data - c#

I have been struggling with this for awhile now. Until now, I have been keeping my backing data of my MVVM project in a singleton class, but that has started to cause problems for me. I am looking for a good way to keep my backing data in a centralized, easily accessible location, but I don't want to make it static and I'm having trouble implementing such a system.
For example, I have a class called GameContainer that holds ObservableCollections of all created objects. I would like to be able to access these ObservableCollections and the object instances contained within throughout my code and I would like to maintain this kind of structure unless there's a better way to do it. If there is a better way, I'd love to learn about it.
I have a method in an initializtion class that, when the program launches, we'll say it creates 10 instances of each object and adds them to the ObservableCollections in GameContainer. So now the ViewModel for my main screen needs access to these objects. Without making GameContainer static, how can my ViewModel access the required data?
Is this a situation that calls for IOC? If so, how could I appropriately implement that?
Any suggestions or advice would be greatly appreciated. I've been at a standstill here recently and I'd love to be able to continue progress on my project.
Thanks. I look forward to seeing what you have to say.

A singleton would generally have a static accessor.
All you need is to have your viewmodels either set a property equal to the GameContainer, or individual properties to the individual memebers of the GameContainer.

Related

How do I run a method from a relative ViewModel and get its return value?

To better show my problem, I drew a graph of how my ViewModel hierarchy looks like so far:
ViewModel hierarchy
What I want to achieve is simply call a method from ScriptEditorViewModel and ask it, if the object, which is currently being edited inside EditObjectViewModel has been specified in the script.
Later I also want to send some information to ScriptEditorViewModel and make it generate a script for the object if it doesn't exist.
ScriptEditorViewModel and ProjectManagementViewModel are 2 separate tabs in my program, which are basically operating at the same time.
Is it possible to do that and if so, is it a good approach?
Note: I'm currently using ReactiveUI as my MVVM framework but any other MVVM solution is also welcome.
When using MVVM pattern, you want to decouple components.
In View part there is xaml with bindings to data and command present in ViewModel.
In ViewModel you should keep data that is presented and logic that does something with that data. It is not the wisest thing to couple multiple ViewModels - keep their logic separated. If you have a command method, all data it deals with should be present in its ViewModel. For anything more complex, you shoud consider communicating with some kind of service or database.
Hence comes the Model part. Here you want to create the model of something you want to store and not necessary present in a View.
I don't know if I understood your problem well, but including a database or any kind of 'persistence layer' into your solution should resolve the problem of accessing specific information. You can create some in-memory storage for start.

Writing a properties aggregator

Background
After spending a lot of time researching, I have not found any way of assigning multiple objects to PropertyGrid (Extended WPF Toolkit). My next idea is to create my own aggregator class that takes in selected objects and exposes their common properties to the outside world. I'll then assign (an instance of) this class to PropertyGrid. Any changes made by the user in PropertyGrid will be passed on to the selected objects by the aggregator class.
Question
Is there anything in the Framework (especially Reflection) that could help me with this task? All objects in my domain inherit from a common ancestor and add new properties of their own (or override ancestor versions). Class hierarchy is multiple levels deep.
UPDATE
For anyone else stuck in the same situation as me, I was able to finally solve PropertyGrid problem. See my other post for the solution.
Hope I can interpret what you want correctly.
One of the idea is using T4ToolBox to generate pre-compile class by scripting (which is also C# code in a template file).
Define your objects that want to be aggregate into xml.
Then you can use reflection to loop through all public method/properties in the objects (based on the xml) to find out the set of common methods
Generate an interface and (if you want) the corresponding concrete classes
One manual work after this is change your original object by implementing the newly generated interface.

Does anything speak against making all domain objects inherit from INotifyPropertyChanged?

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

ViewModel and Singleton Pattern

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/

How to have multiple pairs "View-ViewModel"?

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.

Categories