Showing posts with label Decoupled Architectures. Show all posts
Showing posts with label Decoupled Architectures. Show all posts

Wednesday, March 14, 2012

Using Autofac's Auto-Factories to Avoid Service Locator

An autofac-style factory delegate
An autofac-style factory delegate
(credit: pasukaru76)

I recently switched a project's DI solution from StructureMap to Autofac.

The reason was because the only way I could get StructureMap to handle dynamic instantiation was to use a variant of Service Locator, which couples your code to your container, making unit tests impossible and reducing code coverage.

In this article I'll explain the problem with StructureMap, and how Autofac solved it elegantly.

I'll explain the problem using a Something class, i.e. any class you might want to dynamically instantiate somewhere in your code. Here it is in all it's glory:

public class Something : ISomething
{
    public Something(int anArgument)
    {
        //an implementation
    }
}

How it works in StructureMap
One of the biggest problems with using StructureMap (as mentioned in this post and this post), is that your entry-point to the container is via the static class ObjectFactory, which always resolves to a singleton container.

Commonly you'll see a Bootstrapper class like this one below, where all the dependencies are registered (explained here):

public static void Bootstrap()
{
    ObjectFactory.Initialize(x =>
    {
        x.For<ISomething>().Use<Something>();
        x.For<IAnotherThing>().Use<AnotherThing>();
    }
}

The main benefit of the static reference is that when you need to dynamically instantiate an instance later in your code, you can use the static class again to refer to the same container (rather than 'newing up' an instance of the container, which wouldn't have all of your existing bootstrapped mappings):

public class SomethingClient
{
    public void SomeDynamicScenario(int anArgument)
    {
        var something = ObjectFactory
            .With("anArgument").EqualTo(anArgument)
            .GetInstance<ISomething>();
        //operate on new object
    }
}

The downside of this benefit is that it's a Service Locator. The method can't be unit tested, because when the test runner gets to the ObjectFactory, it doesn't know what an IService is. You could tell it by running the Bootstrapper in your test, but then ofcourse then you aren't unit-testing any more.

In other words, your code is coupled to the StructureMap container.

The standard approach
The standard approach to making this testable is to extract your instantiation logic into an ISomethingFactory. That way, you can inject the factory and mock it in your tests.

public class SomethingClient
{
    private readonly ISomethingFactory somethingFactory;

    public SomethingClient(ISomethingFactory aSomethingFactory)
    {
        somethingFactory = aSomethingfactory;
    }

    public void SomeDynamicScenario(int anArgument)
    {
        var something = somethingFactory.Create(anArgument);
        //operate on new object
    }
}

public class SomethingFactory : ISomethingFactory
{
    public ISomething Create(int anArgument)
    {
        return ObjectFactory
            .With("anArgument").EqualTo(anArgument)
            .GetInstance<ISomething>();
    }
}

But then ofcourse, all you are doing is moving the problem somewhere else. How would you unit test SomethingFactory? You can't.

The problem is that wherever you have 'peppered' container references around your code (i.e. ObjectFactory references), you won't be able to test and your implementation will be coupled.

At that stage you could just say, well, that's the boundary of our unit tests - we will adopt a policy where we just don't unit test factories. And there's merit in that, because you are defining a unit test boundary and everything on one side of it will be unit tested. You could still test the factory as a module, or not test it at all. But then again...

Step in Autofac
The good thing about Autofac is, not only does it provide a solution which gives you 100% code coverage, it's also actually much easier to implement.

You can just declare your factory as a delegate method (which returns an ISomething), include it as a constructor argument and that's it! Autofac will work out from your ISomething mappings to build and inject a factory for you, saving you the bother of having to even define one in the first place.

Here's the SomethingClient example again:

public class SomethingClient
{
    private readonly Func<int, ISomething> somethingFactory;

    public SomethingClient(
                  Func<int, ISomething> aSomethingFactory)
    {
        somethingFactory = aSomethingfactory;
    }

    public void SomeDynamicScenario(int anArgument)
    {
        var something = somethingFactory(anArgument);
        //operate on new object
    }
}

//No need for a factory class

When the container instantiates SomethingClient it discovers the Func delegate. The delegate has a return type that Autofac is registered to handle, and a parameter list Autofac recognises as ISomething constructor parameters, and so Autofac injects a delegate that acts as a factory for us.

The Func delegate in this example takes one int argument, but ofcourse you can plug in any useful combination of input parameters.

Mixed constructor argument parameters
Now, this all works fine when we have a simple parameter with just a single int, but what happens when we update ISomething to accept a mixture of dependencies and value-type arguments?

public class Something : ISomething
{
    public Something(int anArgument,
                      Point aPoint, IDependency aDependency)
    {
        //an implementation
    }
}

In this example let's assume that the Point above is a type you have defined in your codebase to represent a value type, and therefore you want to specify this value dynamically on construction rather than by registering it with the container:

public struct Point
{
    public int X;
    public int Y;
    public Point(int anX, int aY)
    {
        X = anX;
        Y = aY;
    }
}

On the other hand ofcourse, IDependency is a dependency and you want that injected for you, by the container. How do we declare our factory?

We only include the value types and we omit the dependency:

public class SomethingClient
{
    private readonly 
              Func<int, Point, ISomething> somethingFactory;

    public SomethingClient(
              Func<int, Point, ISomething> aSomethingFactory)
    {
        somethingFactory = aSomethingfactory;
    }

    public void SomeDynamicScenario(
                   int anArgument, Point aPoint)
    {
        var something = somethingFactory(anArgument, aPoint);
        //operate on new object
    }
}

//No need for a factory class

No IDependency mentioned anywhere! Autofac is smart enough to allow you to add dependencies to the underlying class constructor's signature, without changing the factory, and it will still inject the dependencies for you!

Which is exactly what you want - as your solution grows and you find yourself adding dependencies, your factories do not change. They are created for you and extra dependencies are included on instantiation transparently.

This type of joined-up thinking makes Autofac a very nice container to work with. Lots of things happen for you, right out of the box, based on convention - you just have to know which and when.

The composition root
As this post eloquently explains, there should be only one place in an application where your container is referenced - the composition root. In this location you should do everything necessary to resolve the entire object graph - i.e. Register, Resolve, Release.

By using a static reference to a singleton container, StructureMap encourages these rules to be broken. Autofac, on the other hand, provides a container that implements IDisposable, which means you can use a using block to enforce the RRR pattern:

public class Program
{
    public static void Main()
    {
        var containerBuilder = registerAssemblyTypes();

        using (var container = containerBuilder.Build())
        {
            //single entry point
            var entryPoint = 
                    container.Resolve<ICodebaseEntryPoint>();
            //start using entryPoint
        }
    }

    private static ContainerBuilder registerAssemblyTypes()
    {
        var programAssembly = Assembly.GetExecutingAssembly();
        var builder = new ContainerBuilder();

        //perform auto-wiring
        builder.RegisterAssemblyTypes(programAssembly)
            .AsImplementedInterfaces();

        return builder;
    }
}

Component discovery
While we're here, take a look at the call to ContainerBuilder.RegisterAssemblyTypes (Assembly). This little call uses reflection to look at your concrete classes and your interfaces, and work out which go with which. It uses a convention over configuration approach, and you can include clauses and overrides to filter and specify particular instantiations.

StructureMap also provides a similar component discovery model.

In fact, I'm sure StructureMap can do most of the things Autofac can do one way or another (see this article on avoiding static references), and I've used StructureMap successfully many times. It's just that Autofac does things nicely by default.

Broadening the discussion about relationships
One final point - Nicholas Blumhardt, the creator of Autofac, has included a very nice chart on his blog describing different object relationship types (of which dynamic instantiation via factories is one):

Relationship Adapter Type Meaning
A needs a B None Dependency
A needs a B at some point in the future Lazy<B> Delayed instantiation
A needs a B until some point in the future Owned<B> Controlled lifetime
A needs to create instances of B Func<B> Dynamic instantiation
A provides parameters of types X and Y to B Func<X,Y,B> Parameterisation
A needs all the kinds of B IEnumerable<B> Enumeration
A needs to know X about B before using it Meta<T> and Meta<B,X> Metadata interrogation

It's nice to consider contextually where the problem we've just dealt with sits. For more discussion on these types, check out Nicholas' introductory article.

Wednesday, July 6, 2011

Introduction to IoC Containers and Dependency Injection using StructureMap

In a previous article, I discussed the nature of the IoC principle as a separate entity from Dependency Injection. In this article I want to explain IoC Containers, and show how these can be used alongside Dependency Injection to create clean, testable, scaleable code, via decoupled architectures.

But before I explain what IoC Containers and DI are, let's talk about why you would want them.

Decoupled Architectures
In my IoC post, we looked at an example in which we handed over control to a GUI framework. I'm going to continue with that example here, and have included a cut-down version of the class in the codeblock below.

(I've renamed the class GuiFramework to GraphicUserInterface, because the original naming was only intended to highlight the differences between libraries and frameworks.)

public class BusinessLogic {

    private GraphicUserInterface gui = 
                    new GraphicUserInterface();

    public void Run(){
        gui.NamePrompt("Please enter your name");
        gui.AddNameChangedHandler(OnNameChanged);
    }
}

public class Program() {
    public static void Main() {
        BusinessLogic busLogic = new BusinessLogic();
        busLogic.Run();
    }
}

One of the main benefits of the IoC approach is that we have a separation of concerns. The GraphicUserInterface class handles all of the stuff to do with GUIs. The BusinessLogic class handles all of the stuff to do with business logic.

The business logic class manipulates the GUI class in order to implement business logic functionality, but it doesn't know anything about how, when or where the GUI does it's job. It simply uses the GUI's services and that's it.

So our architecture is almost decoupled. The only thing that still couples our architecture is that the business logic class directly instantiates an instance of the GraphicUserInterface class. With this setup we say that the BusinessLogic class depends on the GraphicUserInterface class, or that the GraphicUserInterface class is a dependency of the BusinessLogic class.

If we can properly decouple these components, then they become like 'plugins':

  • entirely independent of each other
  • entirely interchangeable with other components that provide the same or similar services
  • but still entirely inter-operable with each other - any plugged in component will work without adapting or making config changes to other components in the system - they will just 'plug and play'

Why That's Good
If you've worked with enterprise-level applications, or any application with more than a trivial number of components, it will be clear why this is positive. Here are a few important reasons:

  • Requirements changes - It is practically inevitable during any project that requirements will change. Decoupled architectures allow you to replace components in an existing system without having to adapt and recompile other components to match.
  • Unit testing - A decoupled component can be tested in isolation from it's dependencies, by mocking the dependencies. In this way unit tests can be run continuously throughout the project - and it becomes easy to have a development process in which your software always in a testable state. This is a huge advantage because it provides certain guarantees and confidence throughout. It also paves the way for TDD, which i'll discuss in another post.
  • Separation of concerns - it enforces an architecture where responsibilities are meted out to components neatly. This is nicer to work with, but it also has the practical benefit that if you bring a new developer onto the project, they can start work very quickly, and with a minimum of knowledge about the system. For example, if they are working on a data-access abstraction they need not ever have seen the UI - the responsibilities that this developer has will end at the boundary of the data-access abstraction, or whatever other component they are working on.

So let's see what that really means, by decoupling the example code, step by step.

Step 1: Use an Interface
Instead of referring to the implementation class directly by name, we'll use an interface. I've commented out the old declaration and added a new one.

public class BusinessLogic {

    //private GraphicUserInterface gui = new
    //                GraphicUserInterface();
    private IUserInterface userInterface;

    public void Run(){
        gui.NamePrompt("Please enter your name");
        gui.AddNameChangedHandler(OnNameChanged);
    }
}

public class Program() {
    public static void Main() {
        BusinessLogic busLogic = new BusinessLogic();
        busLogic.Run();
    }
}

First, notice the rename. The interface is called IUserInterface - not IGraphicUserInterface. This is important, because our business logic class doesn't need to know what kind of implementation it is dealing with. All it needs is the services of some kind of user interface, in order to prompt and accept a user's name. Exactly what kind of UI is unimportant - it could be a GUI or a web form or a speech recognition component - the BusinessLogic class doesn't care.

All the BusinessLogic class wants to know is that the class is capable of providing the services it requires. Implementation classes can indicate this capability by implementing the relevant interface - in this case IUserInterface.

Second, notice that we are not instantiating our new private userInterface member, only declaring it. Ofcourse if our application is going to work, the member will need to be instantiated - but how?

Step 2: Use Dependency Injection
We 'inject' a pre-instantiated object into our class:

public class BusinessLogic {

    private IUserInterface userInterface;

    public void BusinessLogic(IUserInterface aUserInterface){
        this.userInterface = aUserInterface;
    }

    public void Run(){
        gui.NamePrompt("Please enter your name");
        gui.AddNameChangedHandler(OnNameChanged);
    }
}

public class Program() {
    public static void Main() {
        BusinessLogic busLogic = new BusinessLogic();
        busLogic.Run();
    }
}

The approach used above is called Constructor Injection. Alternatively you could use Setter Injection, which is where you inject a dependency via a method (a setter method). In either case, the dependency is instantiated outside of the dependent class and injected in.

We'll use Constructor Injection in this example, and you'll see why a little later on.

Step 3: Set up an IoC Container
So where is the object instantiated? We need an IoC container.

These 'contain' the mappings required to wire up our dependencies. You'll hear them called DI containers too, but it means the same thing (there's a brief discussion on terminology at the bottom of this article).

I'm going to use StructureMap as an example because it's easy to use and has an intuitive syntax. First, we create a Bootstrapper. This becomes the single location within our program where concrete types are mapped to interfaces:

using StructureMap;

public static class Bootstrapper
{
    public static void Bootstrap()
    {
        ObjectFactory.Initialize(x =>
        {
            x.For<IUserInterface>().Use<GraphicUserInterface>();
            x.For<IBusinessLogic>().Use<BusinessLogic>();
        });
    }
}

StructureMap is one of a number of IoC Containers for .NET. Regardless of which container you use, you would expect to see all mappings declared inside a Bootstrapper, and the Bootstrapper to be created during initialisation (Global.asax for web applications, or the main routine for a desktop application).

StructureMap's Object Factory
The ObjectFactory mentioned in the codeblock above is a static wrapper for the StructureMap container. Whenever you use the ObjectFactory static class anywhere in your code, you are always referencing the same singleton container (it is possible to use more than one container object but this is not standard).

Once you have bootstrapped your mappings, you can use the static ObjectFactory reference anywhere in your code to instantiate an object by describing the service you require (passing in an interface name):

public class Program {
    public static void Main()
    {
        Bootstrapper.Bootstrap();
        var userInterface = 
            ObjectFactory.GetInstance<IUserInterface>();
    }
}

In the above example, the implicitly-typed var userInterface will now hold an instance of the GraphicUserInterface class.

Auto-Wiring
You might think at this stage, great - now we can just create a BusinessLogic object and send the userInterface object as an argument. But it's simpler than that, and this is one good reason to use Constructor Injection for your dependencies.

If you decouple all of your components, including (in this case) the BusinessLogic class, then StructureMap will figure out your dependencies for you using Auto-Wiring:

public class Program {

    public static void Main()
    {
        Bootstrapper.Bootstrap();

        //var userInterface = 
        //  ObjectFactory.GetInstance<IUserInterface>();
        var businessLogic = 
            ObjectFactory.GetInstance<IBusinessLogic>();

        businessLogic.Run();
    }
}

Notice that I have commented out the top line. Auto-wiring basically means that unless you tell the bootstrapper differently, any time you instantiate an object with dependencies StructureMap will create an instance of the dependency and inject it for you.

More With StructureMap
There's a lot more you can do with StructureMap, or any IoC Container. For example, you can wire up a singleton so that all dependencies resolve to a single instance:

x => x.For<IFoo>().Singleton().Use<Foo>()

You can use 'open generics', so that you can decouple your genericised classes. For example you might have a class Repository which could handle Book objects or Magazine objects, i.e. Repository<Book> or Repository<Magazine>. Using this syntax, you can declare mappings that are generics-agnostic:

x => x.For(typeof (IRepository<>)).Use(typeof (Repository<>))

You can specify an instance to use for particular constructor arguments. For example, if your class Foo is constructed with a string called argName:

x.For<IFoo>().Use<Foo>().Ctor<string>("argName").Is("arg");
//or
x.For<IFoo>().Use<Foo>().Ctor<string>("argName").
                           .EqualToAppSetting("app-setting-id");

This is ofcourse a whirlwind tour. Here are a few recommended links if you want to run off and figure out StructureMap now:

When To Use Which Approach
There will be times when Constructor Injection is not appropriate, and you need fine-grained control of object instantiation during program execution. In these circumstances you can use the ObjectFactory object as we did in the examples earlier:

var newFoo = ObjectFactory.GetInstance<IFoo>()

This gives you the same type of control over when things are instantiated as you get with ordinary coupled code. But it should be clear that the easiest approach whenever possible is to use Constructor Injection and let Auto-Wiring do the work for you. When this isn't possible move to Setter Injection, and when that isn't possible, use ObjectFactory to create an instance.

Decoupling Your Container
Ofcourse, ObjectFactory is a class defined within the StructureMap namespace. If you pepper it around your code (i.e. using GetInstance), then you are coupling your code to StructureMap. Some people prefer to ensure full decoupling from IoC Containers by housing Container references within custom object factories, and accessing those factories via an interface.

In another post I will discuss Autofac, a google code project and DI/IoC Container. Autofac, unlike StructureMap, ensures the container is fully decoupled by design. Instead of using a generic static Object Factory, Autofac allows you to create and inject custom object factories for use in your code.

The IoC/DI Name
You can see Martin Fowler here discussing the evolution of the name. Three different techniques / approaches have merged together to form a pattern, and so we have this composite name - IoC / DI / Container.

You can see what I mean if you consider that it's perfectly possible to use Dependency Injection without inverting control, or decoupling via interfaces:

public class BusinessLogic {

    private SomeLibrary someLibrary;

    public void BusinessLogic(SomeLibrary someLib){
        this.someLibrary = someLib;
    }
}

It's also possible to invert control without using DI, or to use containers without DI or IoC. However these approaches have grown to compliment each other and have become a mainstream approach to creating clean, testable, scaleable application architecures.