Click here to Skip to main content
15,886,740 members
Articles / Programming Languages / XML

Implementing MVVM Light with Structure Map

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
9 Dec 2011CPOL3 min read 34.8K   763   6  
This article is about implementing an MVVM Light based solution with an IoC container other than the built-in SimpleIoC container included in the MVVM Light framework.
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Fujitsu Canada
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions