The code for this step is located on github.

In the previous post, we added support for singleton and transient lifetimes. But the last couple of posts have made our syntax look a bit unwieldy and is somewhat limitting when looking towards the future, primary when needing to detect cycles in the resolution chain. So today, we are going to refactor our code by introducing a new class ResolutionContext. This will get created everytime a Resolve call is made. There isn’t a lot to say without looking at the code, so below is the ResolutionContext class.

public class ResolutionContext
{
    private readonly Func<Type, object> _resolver;

    public Registration Registration { get; private set; }

    public ResolutionContext(Registration registration, Func<Type, object> resolver)
    {
        Registration = registration;
        _resolver = resolver;
    }

    public object Activate()
    {
        return Registration.Activator.Activate(this);
    }

    public object GetInstance()
    {
        return Registration.Lifetime.GetInstance(this);
    }

    public object ResolveDependency(Type type)
    {
        return _resolver(type);
    }

    public T ResolveDependency()
    {
        return (T)ResolveDependency(typeof(T));
    }
}

Nothing in this is really that special. The Activate method and the GetInstance method are simply here to hide away the details so the caller doesn’t need to dot through the Registration so much (Law of Demeter). The Funcis still here, but this is where it stops. Shown below, our IActivator and ILifetime interfaces now take a ResolutionContext instead of the delegates.

public interface IActivator
{
    object Activate(ResolutionContext context);
}

public interface ILifetime
{
    object GetInstance(ResolutionContext context);
}

Now, they look almost exactly the same, so, as we discussed in the last post, the difference is purely semantic. Activators construct things and Lifetimes manage them.

Finally, no new tests have been added, but a number have changed due to this refactoring. I’d advise you to check out the full source and look it over yourself. In our final post, we’ll be handling cyclic dependencies now that we have an encapsulated ResolutionContext to track calls.

The code for this step is located on github.

We left off the previous post with the need to support different lifetime models such as Singleton, Transient, or per Http Request. After our last refactoring, this is actually a fairly simple step if we follow the single responsiblity principle and define the roles each of our abstractions play.

Currently, we only have 1 abstraction which is around activation. It would be fairly simple to use activators to handle lifetime as well, but things will quickly become complex if we go this route. Therefore, we will define an activator’s job as activating an object. In other words, it’s only job is to construct an object using whatever means it wants, but it should never store the instance of an object in order to satisfy a lifetime requirement.

In order to manage lifetimes, we will introduce a second abstraction called an ILifetime. It’s sole job is to manage the lifetime of an activated object. It can(and will) use an activator to get an instance of an object, but it will never construct one itself.

By keeping these two ideas seperate, it makes this a fairly trivial addition. Below are the two tests for this functionality, one for transient and one for singletons.

public class when_resolving_a_transient_type_multiple_times : ContainerSpecBase
{
    static object _result1;
    static object _result2;

    Because of = () =>
    {
        _result1 = _container.Resolve(typeof(DummyService));
        _result2 = _container.Resolve(typeof(DummyService));
    };

    It should_not_return_the_same_instances = () =>
    {
        _result1.ShouldNotBeTheSameAs(_result2);
    };

    private class DummyService { }
}

public class when_resolving_a_singleton_type_multiple_times : ContainerSpecBase
{
    static object _result1;
    static object _result2;

    Establish context = () =>
        _container.Register().Singleton();

    Because of = () =>
    {
        _result1 = _container.Resolve(typeof(DummyService));
        _result2 = _container.Resolve(typeof(DummyService));
    };

    It should_return_the_same_instances = () =>
    {
        _result1.ShouldBeTheSameAs(_result2);
    };

    private class DummyService { }
}

You see above that we are making transient the default lifetime and adding a method to set a singleton lifetime.

public interface ILifetime
{
    object GetInstance(Type type, IActivator activator, Func<Type, object> resolver);
}

public class TransientLifetime : ILifetime
{
    public object GetInstance(Type type, IActivator activator, Func<Type, object> resolver)
    {
        return activator.Activate(type, resolver);
    }
}

public class SingletonLifetime : ILifetime
{
    private object _instance;

    public object GetInstance(Type type, IActivator activator, Func<Type, object> resolver)
    {
        if (_instance == null)
            _instance = activator.Activate(type, resolver);
        return _instance;
    }
}

So, an ILifetime has a single method that takes the type, the activator, and the resolver. We are going to clean this up in the next installment, but regardless, these implementations are still relatively simple.

The TransientLifetime is basically a pass-through on the way to the activator. It doesn’t store anything, so it has no need to do any interception. The SingletonLifetime, however, only activates an object once, stores the instance, and then returns that instance everytime. I haven’t included threading in here, but a simple lock would suffice for most cases.

We need to add a Lifetime and a Singleton method onto our Registration class:

public class Registration
{
    //other properties

    public ILifetime Lifetime { get; private set; }

    public Registration(Type concreteType)
    {
        ConcreteType = concreteType;
        Activator = new ReflectionActivator();
        Lifetime = new TransientLifetime();

        Aliases = new HashSet();
        Aliases.Add(concreteType);
    }

    //other methods

    public Registration Singleton()
    {
        Lifetime = new SingletonLifetime();
        return this;
    }
}

Finally, we just need to change the Resolve method in our Container class to use the Lifetime as opposed to the Activator and we are all done.

public object Resolve(Type type)
{
    var registration = FindRegistration(type);
    return registration.Lifetime.GetInstance(registration.ConcreteType, registration.Activator, Resolve);
}

In our next post, we’ll do some refactoring ultimately to support handling cyclic dependencies. A by product of this is a better coded container. See you then…

The code for this step is located on github.

From our previous post, we added the ability to register dependencies with dependencies that couldn’t be resolved by the container.  These would be dependencies like primitives or abstractions like interfaces.  In this post, we are going to solve our inability to resolve an abstraction by adding aliases to the Registration class.

Below is our test for this functionality:

public class when_resolving_a_type_by_its_alias : ContainerSpecBase
{
    static object _result;

    Establish context = () =>
        _container.Register<DummyService>().As<IDummyService>();

    Because of = () =>
        _result = _container.Resolve(typeof(IDummyService));

    It should_not_return_null = () =>
        _result.ShouldNotBeNull();

    It should_return_an_instance_of_the_requested_type = () =>
        _result.ShouldBeOfType<DummyService>();

    private interface IDummyService { }
    private class DummyService : IDummyService { }
}

Above, the only difference from an API standpoint is the addition of the “As” method. This is basically telling the container that DummyService should be returned when IDummyService is requested.

So, the first change we’ll make is on the Registration class. We’ll add a property called Aliases. Aliases will include all the types that should resolve to the same concrete class including the concrete version. So, Register().As().As() will resolve when any of the types ISomeServiceA, ISomeServiceB, or SomeService is requested. Our new registration class looks like this:

public class Registration
{
    public Type ConcreteType { get; private set; }

    public IActivator Activator { get; private set; }

    public ISet<Type> Aliases { get; private set; }

    public Registration(Type concreteType)
    {
        ConcreteType = concreteType;
        Activator = new ReflectionActivator();

        Aliases = new HashSet<Type>();
        Aliases.Add(concreteType);
    }

    public Registration ActivateWith(IActivator activator)
    {
        Activator = activator;
        return this;
    }

    public Registration ActivateWith(Func<Type, Func<Type, object>, object> activator)
    {
        Activator = new DelegateActivator(activator);
        return this;
    }

    public Registration As<T>()
    {
        Aliases.Add(typeof(T));
        return this;
    }
}

The only other change we need to make is in the container where we are trying to find a registration.

private Registration FindRegistration(Type type)
{
    var registration = _registrations.FirstOrDefault(r => r.Aliases.Contains(type));
    if (registration == null)
        registration = Register(type);

    return registration;
}

That’s it! All the tests should still pass and all is good with the world. In the next post, we are going to talk about lifetimes (Singleton, Transient, PerRequest, etc…) and how to add them into our container.

Stay Tuned.

The code for this step is located on github.

From our previous post, we are able to resolve types with dependencies that they themselves can be resolved.  We all know from experience that this is hardly ever true without some help.  For instance, a type that takes an integer in its constructor would be impossible to resolve in our current state.  To combat this, we are going to create something called an activator.  It’s entire purpose is to, given a type, give back an instance of that type through construction.  The interface is defined below:

public interface IActivator
{
    object Activate(Type type, Func<Type, object> resolver);
}

Nothing special here, but what is special is the abstraction we are creating between the activation of an instance and the implementation.  Our first implementation will be to refactor the current activation code embedded in the Resolve method of the container into a new activator called a ReflectionActivator.

public class ReflectionActivator : IActivator
{
    public object Activate(Type type, Func<Type, object> resolver)
    {
        var ctor = type.GetConstructors()
                       .OrderByDescending(c => c.GetParameters().Length)
                       .First();

        var parameters = ctor.GetParameters();
        var args = new object[parameters.Length];
        for (int i = 0; i < args.Length; i++)
            args[i] = resolver(parameters[i].ParameterType);

        return ctor.Invoke(args);
    }
}

With the exception of the resolver Func that is passed in and its usage, this code is identical to the Resolve method.  The resolver argument has the same signature as the Resolve method, thereby allowing us to perform the same recursion we were using previously.  We can now replace the existing code in Resolve with the below method:

public object Resolve(Type type)
{
    var activator = new ReflectionActivator();
    return activator.Activate(type, Resolve);
}

At this point, all our existing tests should still pass (because we really haven’t done anything).  Let’s go ahead and refactor some more allowing different types to be registered with their own settings.  This is the final refactoring before we can solve the original stated problem.

Below is the Registration class.  It has a property called ConcreteType.  I’m naming it that because I know some things about the future that you don’t, but regardless, it holds the actual type that can be constructed.

public class Registration
{
    public Type ConcreteType { get; private set; }

    public IActivator Activator { get; private set; }

    public Registration(Type concreteType)
    {
        ConcreteType = concreteType;
        Activator = new ReflectionActivator();
    }

    public Registration ActivateWith(IActivator activator)
    {
        Activator = activator;
        return this;
    }

    public Registration ActivateWith(Func<Type, Func<Type, object>, object> activator)
    {
        Activator = new DelegateActivator(activator);
        return this;
    }
}

The take away from the class above is that we have a ConcreteType that has an instance of IActivator associated with it.  Therefore, an unresolvable ConcreteType can be activated differently than one that is resolvable.  For instance, the implementation of the IActivator that solves our original problem is called the DelegateActivator.

public class DelegateActivator : IActivator
{
    private readonly Func<Type, Func<Type, object>, object> _activator;

    public DelegateActivator(Func<Type, Func<Type, object>, object> activator)
    {
        _activator = activator;
    }

    public object Activate(Type type, Func<Type, object> resolver)
    {
        return _activator(type, resolver);
    }
}

Yes, that is a Func that takes a Func as an argument.  This will get cleared up in a future refactoring, but for now, this is actually quite simple.  The nested Func argument is the Resolve method (give me a type, and I’ll give you back an instance).  So, that last thing to do is to refactor the Container class to use the Registration class and the Activators.

public class Container
{
    private List<Registration> _registrations = new List<Registration>();

    public Registration Register(Type type)
    {
        var registration = new Registration(type);
        _registrations.Add(registration);
        return registration;
    }

    public Registration Register<T>()
    {
        return Register(typeof(T));
    }

    public object Resolve(Type type)
    {
        var registration = FindRegistration(type);
        return registration.Activator.Activate(type, Resolve);
    }

    public T Resolve<T>()
    {
        return (T)Resolve(typeof(T));
    }

    private Registration FindRegistration(Type type)
    {
        var registration = _registrations.FirstOrDefault(r => r.ConcreteType == type);
        if (registration == null)
            registration = Register(type);

        return registration;
    }
}

Just to note, we are allowing the resolution of types that have not been explicitly registered with the container.  I believe that some other notable IoC container authors disagree with this practice, namely Krzysztof Koźmic and Nicolas Blumhardt.  Their reasoning is that without explicit configuration, it is easy for the container to misbehave.  I say, have enough tests so that doesn’t become an issue.  Regardless, this is how it is coded and if you disagree, rip out that part and throw an exception.

One other thing to note is that we are not threadsafe. This would be relatively simple to add using the new concurrent collection types in .NET 4.0. I’ll leave that to you to play around with.

Below is the new test we have added for this batch of functionality:

public class when_resolving_a_type_with_unresolvable_dependencies : ContainerSpecBase
{
    static object _result;

    Establish context = () =>
        _container.Register<DummyService>()
            .ActivateWith((t, r) => new DummyService(9, (DepA)r(typeof(DepA))));

    Because of = () =>
        _result = _container.Resolve(typeof(DummyService));

    It should_not_return_null = () =>
        _result.ShouldNotBeNull();

    It should_return_an_instance_of_the_requested_type = () =>
        _result.ShouldBeOfType<DummyService>();

    private class DummyService
    {
        public DummyService(int i, DepA a)
        { }
        }

    private class DepA { }
}

Like I said above, a little ugly with that ActivateWith call. It is saying to use 9 for the integer and resolve DepA from the container.

In the next post, we’ll get into how to handle resolving IDummyService, which is basically the whole point of this exercise. Stay tuned…

The code for this step is located on github.

In the previous post, we created our first test and our container implementation.  It is very simple and only resolves types with default constructors. In the installment, we’ll take this a step further and resolve types by discovering it’s constructors parameters and resolving them as well.

But first, let’s write a test to show us exactly what we are trying to do.

public class when_resolving_a_type_with_dependencies : ContainerSpecBase
{
    static DummyService _result;

    Because of = () =>
        _result = (DummyService)_container.Resolve(typeof(DummyService));

    It should_not_return_null = () =>
        _result.ShouldNotBeNull();

    It should_return_an_instance_of_the_requested_type = () =>
        _result.ShouldBeOfType<DummyService>();

    It should_return_an_instance_with_the_dependency_created = () =>
        _result.A.ShouldNotBeNull();

    private class DummyService
    {
        public DepA A { get; private set; }

        public DummyService(DepA a)
        {
            A = a;
        }
    }

    private class DepA { }
}

As you can see, when constructing DummyService, we must provide it with an instance of DepA.  Currently, this test will fail because our current implementation assumes a default constructor exists.  Let’s remove that assumption.

public class Container
{
    public object Resolve(Type type)
    {
        var ctor = type.GetConstructors()
            .OrderByDescending(c => c.GetParameters().Length)
            .First();

        var parameters = ctor.GetParameters();
        var args = new object[parameters.Length];
        for (int i = 0; i < args.Length; i++)
            args[i] = Resolve(parameters[i].ParameterType);

        return ctor.Invoke(args);
    }

    public T Resolve<T>()
    {
        return (T)Resolve(typeof(T));
    }
}

Simpler than you thought, huh?  Let’s walk through this real quick.  First, we get the constructor that has the most parameters.  If we wanted, this could be published as an extensibility point to allow a consumer to alter the strategy of how to select a constructor.  However, this fits our needs just fine.  After this, we simply iterate through all the parameters of the constructor and recursively call Resolve for each and store the result in the args array.  Finally, we invoke the constructor with all the args.

In the next post, we’ll discuss how to deal with types that can’t be resolved using the above method.