Moving between different IoC containers

I must admit that I always prefer castle Windsor over other IoC containers, but the main reason is that I’m really used to it and all its facilities. I know how to write facilities, and I know how it behave, this makes difficult for me moving to other Container because I usually need time to find how to do same stuff I do with castle with the new Toy.

Actually I’m using Unity sometimes and today I need to mimic the IStartable facility of Castle, because I need Start method to be called whenever the object gets registered, and stop called when the container is disposed. The very first tentative is this code.

public class StartableBuilderStrategy : BuilderStrategy
{
    public override void PostBuildUp(IBuilderContext context)
    {
        base.PostBuildUp(context);
        if (context.Existing is IStartable)
        {
            ((IStartable)context.Existing).Start();
        }
    }

    public override void PreTearDown(IBuilderContext context)
    {
        if (context.Existing is IStartable)
        {
            ((IStartable)context.Existing).Stop();
        }
        base.PreTearDown(context);
    }
}

This code seems to me legitimate to write, but I encounter a problem, when I dispose the container the PreTearDown method is not called. This happens because the PreTearDown method is called only when someone explicitly calls TearDown on the Unity container actually asking the container to teardown the object. Actually I do not like very much how unity track lifetime of object and I suggest you reading this post for a good introduction on the subject, but in my situation I only need these two feature for singleton object (ContainerControlledLifetimeManager).

  1. When the object get constructed I want its start method called
  2. When the container gets disposed I want the method stop called.
  3. Create the object (and call start) when the object is registered in the container

With unity you can solve these two point with really few lines of code, first of all if you want a method to be called when the object gets constructed you can both call the method in the constructor (if any) or you can use a specific attribute

[InjectionMethod]
public void Start()
{

The InjectionMethod attribute gets called after the object is constructed without the need of any other configuration, for the point 2 simply implement IDisposable and call Stop in the Dispose Method. This is still not the very same behavior of Castle Startable facility, because it starts the object immediately upon its registration. The purpose of Startable Facility is the ability to being able to start objects during registration and not when they are first used to resolve a dependency. In unity you can mimic this adding this extension

public class StartableExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Context.Registering += Context_Registering;
    }

    void  Context_Registering(object sender, RegisterEventArgs e)
    {
        if (typeof(IStartable).IsAssignableFrom(e.TypeTo))
        {
            Container.Resolve(e.TypeFrom);
        }
    }
}

public interface IStartable
{

}

As you can see the IStartable interface does not define any method, because actually Start() and Stop() should be called with the InjectionMethodAttribute and IDisposable, but it is needed only to automatically create an instance of the type during registration.

Gian Maria.

Published by

Ricci Gian Maria

.Net programmer, User group and community enthusiast, programmer - aspiring architect - and guitar player :). Visual Studio ALM MVP

3 thoughts on “Moving between different IoC containers”

  1. Actually, the Startable facility does not resolve/create the objects when they are registered, but as soon as all their dependencies can be satisfied.
    Your approach is brittle: if you register a your startable component before its dependencies, you’ll get runtime exceptions.

  2. thanks for the clarification, actually I still use old version of Castle in many of my project and still the documentation refers to the old behavior (http://docs.castleproject.org/Default.aspx?Page=Startable-Facility&NS=Windsor&AspxAutoDetectCookieSupport=1).

    Clearly this approach forces you to register all dependencies before you register your startable object, a better approach is to have a global “Start” on the container that can be called explicitly when all the component are registered.

  3. I don’t think the behavior was changed. The documentation does not say so explicitly, but it also does not contradict it:

    “The objects are instantiated eagerly, that means container will create the first instance without you having to explicitly call container.Resolve”

    By eagerly they mean that the component will be created without you resolving it, but it does not mean it is created at registration time. The actual behavior is that it waits for all the dependencies to be satisfied first.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.