This question might look naive, but I couldn't understand this code in the ViewModelLocator.cs file:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
I see that we use a DataService to get data (from WCF service for example) and assigning it to the MainViewModel. But what if I'm registering more than one ViewModel? like this:
static ViewModelLocator()
{
....
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<Page2ViewModel>();
}
and let's say I have another DataService (DataService2 for example), but this one I'll use with the Page2ViewModel. how can I do that?
Also, if someone can help me (or even give me a link to read) about the above code. I have no clue what it means.
You are not assigning any
IDataService
to theMainViewModel
here. You are registering a type mapping, so your container will be aware that it should return aDataService
whenever anIDataService
required.This is related to dependency injection http://en.wikipedia.org/wiki/Dependency_injection
The DI container auto-wires the dependencies, so when you need a specific type, you can call
ServiceLocator.Current.GetInstance<IDataService>()
or
etc. If it can build it (so you registered your types), it will resolve the full dependency graph for you.
For example, if your
MainViewModel
has a constructor dependency onIDataService
, and you are not in design mode, aDataService
will be injected to theMainViewModel
constructor. Don't be afraid from the buzzword injected, it is just a call to the MainViewModel constructor with the appropriate parameters :).So,
MainViewModel
will not interference withPage2ViewModel
here.I made a simple sample for you to demonstrate what happens (I used Unity, http://unity.codeplex.com/ , but the syntax is almost the same):
the output is:
Because you need a
MainViewModel
(maybe in SimpleIoC you need to register MainViewModel too, in Unity, it can resolve concrete classes without mapping), the container trying to create one, but it realizes thatMainViewModel
needs anIService
, and it finds the default one from the mapping, which isService1
, but it realizes thatService1
needs anIRepository
, and it finds the default one, so it can pass aRepository
to theService1
constructor, then theService1
instance to theMainViewModel
constructor. All the dependencies resolved.The
Foo
call is an example how you can register more than one type to the same interface. Dependency injection is a much more bigger topic, but auto-wiring is an important part of it.