Reputation: 2651
I'm currently setting up the structure for a simple editor for a game I'm working on. This editor will basically load/save a serialized file, which is then used by the game to do whatever it desires.
I see this serialized file pretty much as a database, as it contains data that's constantly used by multiple views, possibly at the same time. As a result of that thought I figured to have all this data (lists of objects, strings, integers, whatever) in a centralized location which all views can read, update, add to, etcetera.
My first thought would go to a singleton class which has a reference to the deserialized data, then databind that accordingly so all open views recieve a notification when something changes at any time.
But I was wondering, is there a way WPF would like you to solve this rather than (directly) binding to a singleton, static data, or a proxy property (property in a datacontext which just returns the data from the singleton)? Or is this just the way to go?
Upvotes: 1
Views: 1948
Reputation: 17402
As mentioned in the comments, the easiest way to share "data" between ViewModel is to pass a reference into them once each one is instantiated.
var sharedModel = new SharedModel();
var viewModel1 = new ViewModel1(sharedModel);
var viewModel2 = new ViewModel2(sharedModel);
Ctor for one of the shared ViewModel's will have whatever Model's that are required as a parameter.
public ViewModel1(SharedModel model) { ... }
If you do not want to manually 'inject' each dependency into associated ViewModel's, you can use Unity, which is an Inversion of Control (IoC) container that will automatically inject applicable dependencies into your ViewModels via Dependency Injection (DI). With DI, you typically would want an associated Interface for each Model so that you are not using concrete types. You can also register concrete types as well.
So, for example, the new shared Model will look like:
public class SharedModel : ISharedModel { ... }
and the ViewModels that need it, will have a new constructor and also an interface
public class ViewModel1 : IViewModel1
{
public ViewModel1(ISharedModel model) { ... }
}
then, using Unity you can Register your ViewModels and Models into the same IoC.
var container = new UnityContainer();
// this will cause the Model to only be created once and shared to other types that have been registered in the container
//
container.RegisterType<ISharedModel, SharedModel>(new ContainerControlledLifetimeManager());
container.RegisterType<IViewModel1, ViewModel1>();
container.RegisterType<IViewModel2, ViewModel2>();
So now, everything lives in the Unity container. Once you Resolve needed ViewModels there is no need to automatically inject any dependencies, Unity will take care of it for you.
var viewModel1 = container.Resolve<IViewModel1>();
If you want to learn more about DI and Unity, take a look at: http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx
Upvotes: 3