|
MVVM Light 4.0 supports the Common Service Locator library, this library contains a shared interface supporting an abstraction over IoC containers and service locators. For More references go to http://commonservicelocator.codeplex.com/
The shared interface supports adapter for
Castle Windsor
Spring .NET
Unity
StructureMap
Autofac
MEF and
LinFu
MVVM Light implements a built-in IoC and adapter supporting the Common Service Locator, leaving the developper free to use whatever Ioc container or service locator with the proper adapter.
This article tries to show how to implement an MVVM Light solution with an IoC container other than the built-in SimpleIoC container. To properly understand this article a basic understanding of MVVM Light, IoC concepts, MVVM and Common Service Locator library is assumed.
The first step is to chose the IoC container, in this article, MVVM Light will be implemented with an Structure Map IoC Container. Why this one? There is not an specific reason to use this container, it was just picked randomly, the only criteria for this article was the IoC container must support a fluent configuration interface.
Then it is neccessary to create a new MVVM Light projet named "DemoStructureMapMVVMLight" (in this article the chosen template was MVVMLight(WPF4), and add a new folder named "Lib" containing the files
StructureMap.dll
StructureMapAdapter.dll
Add a reference to this files.
By default the framework profile is ".Net Framework 4.0 Client", change the profile to ".Net Framework 4.0"
Your project tree must look like this:
There is at least a couple of ways to insert the new IoC container in MVVM Light, the simplest way is to modify the ViewModelLocator.
In this case a new class SMViewLocator will be created, and the current class ViewModelLocator is erased.
The new class is defined in this way
using DemoStructureMap.Model;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using StructureMap;
using StructureMap.Configuration.DSL;
using StructureMap.ServiceLocatorAdapter;
using System.Reflection;
namespace DemoStructureMap.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// <para>
/// Use the <strong>mvvmlocatorproperty</strong> snippet to add ViewModels
/// to this locator.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm/getstarted
/// </para>
/// </summary>
public class SMViewModelLocator
{
}
}
The first thing to do is to configure the container, this logic depends of the implemented container, in the case of a container like Unity, the configuration is done by a xml file, in this case the configuration is done by code.
The configuration fonction will return an instance of IServiceLocator interface, this is the common shared interface in the Common Service Locator library to query the container.
The code for the function is
private static IServiceLocator CreateServiceLocator()
{
Registry registry = new Registry();
registry.ScanAssemblies().IncludeAssembly(Assembly.GetExecutingAssembly().FullName);
if (ViewModelBase.IsInDesignModeStatic)
{
registry.ForRequestedType<IDataService>().TheDefaultIsConcreteType<Design.DesignDataService>();
}
else
{
registry.ForRequestedType<IDataService>().TheDefaultIsConcreteType<DataService>();
}
IContainer container = new Container(registry);
return new StructureMapServiceLocator(container);
}
With Structure Map ther is no need to register each class in the project, the line
registry.ScanAssemblies().IncludeAssembly(Assembly.GetExecutingAssembly().FullName);
registers all classes in the executing assembly, with default container each class must be registerd like this:
SimpleIoc.Default.Register<MainViewModel>(); if there is a lot of models each model must be registered in this way
A new static constructor is needed to assign the newly created interface instance to the service locator:
static SMViewModelLocator()
{
var ioc = CreateServiceLocator();
ServiceLocator.SetLocatorProvider(() => ioc);
}
For every model in the solution there will be a model accessor in this way
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
And finally there is a cleanup function to execute when the main window is closed
public static void Cleanup()
{
//Clean up code
}
Conclusion
With the new support for the Common Service Locator library, change the IoC container in a MVVM Light implementation is very easy.
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.