Using Autofac as an IoC Container in Silverlight Applications

LogoThe subject of Dependency Injection (DI) and Inversion of Control (IoC) containers has received a lot of attention over the last few years.  Building applications that are loosely coupled has become more and more popular (and for good reason) especially in applications that have a lot of dependencies that could break over time or need to handle the addition of new modules seamlessly.  From a personal standpoint I fall somewhere in the middle of the overall DI argument.  I definitely feel that DI has its place and personally use the general pattern in applications but also feel that some use DI in ways that seem to make applications overly complex and more difficult to maintain in the future.   My opinion on the subject really doesn’t matter here though since this post is about using an IoC container framework in Silverlight applications. 

I’ll walk through a simple example from an existing application that my company is working on and demonstrate how using a dependency injection pattern can help minimize code and simplify changes down the road.  If you’re new to the concept of DI and IoC containers I’d recommend reading Martin Fowler’s post on the subject.  He provides a good introduction to constructor, setter and interface injection.  If I had to sum up DI and the purpose of IoC Containers in a single sentence here’s what I’d say:

Minimize hard coded class names when creating object instances and let IoC containers dynamically look-up types and “inject” them into your application at runtime.

Before jumping into using Autofac in Silverlight let’s take a quick look at the type of problem an IoC container can solve.  The following code shows a ViewModel class (see my post of using the MVVM pattern with Silverlight if you’d like more information on what  a ViewModel is) that has two constructors:

 

public class JobChangeOrdersViewModel : JobMaterialsViewModelBase
{
    public JobChangeOrdersViewModel() : this(new ServiceProxy()) { }

    public JobChangeOrdersViewModel(IServiceProxy proxy) : base(proxy)
    {
        if (!this.IsDesignTime)
        {
            //Communicate with another ViewModel (JobManagementViewModel) to get current JobID by using events
            JobManagementEventBus.JobReturned += JobManagementEventBus_JobReturned;
            JobManagementEventBus.OnJobRequested(this, EventArgs.Empty);
            JobManagementEventBus.JobMaterialsUploading += JobMaterialsUploading;
            WireCommands();
            GetChangeOrders();
        }
    }
}


Notice that the first constructor forwards a new ServiceProxy object instance to the second constructor which accepts an IServiceProxy type.  XAML views (Silverlight pages or user controls) call this first constructor to create a ViewModel instance and access data.  While there’s nothing wrong with this code, if I need to change the type of service proxy object used I’d have to change the new ServiceProxy() line of code.  Since Visual Studio provides nice search and replace functionality it’s really easy to do that across multiple files.  However, a better solution would be to define the type of service proxy object to use in one place so it’s easy to locate and easy to change and then “inject” it into the application at runtime.  I use the same two constructor signatures across many ViewModel classes so this centralized-code approach is definitely preferred. Let’s look at how Autofac can be used to avoid hard coding the new ServiceProxy() call.

Getting Started with AutoFac in Silverlight

There are several different IoC containers that can be used with Silverlight such as Unity (included with the Prism framework), Ninject, Caliburn and MEF (an extensibility framework that can act like an IoC container).  I’ve always liked Autofac mainly because it’s very easy to use and a project I’ve followed for awhile. Autofac can be used in ASP.NET, Windows Forms, WPF (or any .NET application) and Silverlight applications so it’s very flexible.  A specific Autofac download for Silverlight 3 (or higher) is available from http://code.google.com/p/autofac/downloads/list.

To get started place the Autofac.dll assembly in your project’s bin folder and add a reference to it using Add Reference.  Once that’s done you can create a ContainerBuilder object instance (located in the Autofac.Builder namespace) and use it to build a Container that can resolve specific types against interfaces (more on this later).  For the code shown above this means that I can associate the ServiceProxy class with the IServiceProxy interface so that anytime I need to supply an object of type IServiceProxy an instance of ServiceProxy will be created and passed behind the scenes.  I created the following class named IoCContainer to handle creating the ContainerBuilder and Container:

public static class IoCContainer
{
    public static IContainer BaseContainer { get; private set; }

    public static void Build()
    {
        if (BaseContainer == null)
        {
            var builder = new ContainerBuilder();
            builder.Register<ServiceProxy>().As<IServiceProxy>();
            BaseContainer = builder.Build();
        }
    }

    public static TService Resolve<TService>()
    {
        return BaseContainer.Resolve<TService>();
    }
}


The Build method handles creating the ContainerBuilder which is used to associate classes with interfaces.  In this case I associate ServiceProxy with IServiceProxy using the Register<TService>() method.  This is a simple example (simple on purpose) but keep in mind that an application can register many associations between types and interfaces as needed.  More advanced associations can also be registered using Autofac including passing parameters to a resolved object’s constructor.  See the Autofac wiki documentation for additional details.  Once the type is registered the ContainerBuilder object’s own Build() method is called which returns an IContainer type (a Container object that can be used to resolve an interface with an object instance). The Resolve<TService>() method added into the IoCContainer class wraps a call to the Container object’s Resolve<TService>() method.  It’s added purely for convenience to save a little code.

In the App.xaml.cs file’s Application_Startup event handler I add the following code which calls the IoCContainer class’s static Build() method:

 

private void Application_Startup(object sender, StartupEventArgs e)
{
    IoCContainer.Build();
    ProcessInitParams(e.InitParams);
    this.RootVisual = new MainPage();
}


Once that’s done the Autofac container can be used to resolve interfaces.  An example of using the IoCContainer class and Autofac classes to create the ServiceProxy object shown earlier in a ViewModel class is shown next:

public class JobChangeOrdersViewModel : JobMaterialsViewModelBase
{
    public JobChangeOrdersViewModel() : this(IoCContainer.Resolve<IServiceProxy>()) { }

    public JobChangeOrdersViewModel(IServiceProxy proxy) : base(proxy)
    {
        if (!this.IsDesignTime)
        {
            //Communicate with another ViewModel (JobManagementViewModel) to get current Job
            JobManagementEventBus.JobReturned += JobManagementEventBus_JobReturned;
            JobManagementEventBus.OnJobRequested(this, EventArgs.Empty);
            JobManagementEventBus.JobMaterialsUploading += JobMaterialsUploading;
            WireCommands();
            GetChangeOrders();
        }
    }
}

You can see that the new ServiceProxy() code originally in the first constructor has been replaced with the IoCContainer code instead.  If a different class needs to be used instead of ServiceProxy then a change can be made in the IoCContainer class’s Build() method and all calls that need to resolve the IServiceProxy interface will automatically be updated throughout the application (which is obviously a good thing as far as maintenance goes). 

There’s much more than can be done with Autofac - this post has only scratched the surface. However, you should have a better understanding of how Autofac (or any compatible IoC container for that matter) can be used in a Silverlight application to keep code loosely coupled.

 

 

 

Print Silverlight 3 or higher screens and generate PDF documents with SmartPrint for Silverlight.

Published Sunday, January 3, 2010 12:31 AM by dwahlin
Filed under: , , ,

Comments

No Comments