Julian Jelfs’ Blog

IoC container is not an uber-factory

Posted in Castle by julianjelfs on July 27, 2009

When I first started seriously using IoC techniques in my application I think I missed the point and I think it is easy to do so. Given that you suddenly have this magical container that you can call Resolve<T> on to get hold of an instance of anything you like, my first temptation was to simply pass around a reference to the container. This is great I thought, because now my classes only need to be dependent on the container.

This is completely the wrong way to think but I never found much guidance to tell me that. Why is it wrong? Firstly because it makes your class dependent on the container and hides the things that it is really dependent on from the consumer code. Secondly, it makes your class impossible to use without using the container. Thirdly, it makes your class difficult to test.

This did not seem obvious to me at the time, but the truth is that you only want to reference your container in one place and that is when you bootstrap the application. For a web application this probably needs to happen in the Application_Start event from Global.asax. From that point on, dependencies are just added to the constructors of your classes and the container resolves those dependencies, but the classes themselves have no knowledge that their dependencies have been resolved by the container. This means that you have a choice whether to use the container or not – your class does not care. So if you wish to instantiate your class directly (in a unit test for example to inject mocks) then you can do so.

I think that one of the reasons I went down the wrong route to start with was because I couldn’t see how to deal with objects whose construction is out of your control. A good example of such an object is a WebForm or a UserControl in Asp.Net. If you are not allowed to reference the container directly in your code, then how do you satisfy your dependencies in such circumstances?

One answer is to set up a layer of indirection between your code and your container. This can take the form of a static Action defined in a location accessible to all of the code that might need to use this technique and also accessible from your bootstrapper. Initially this Action is set to null (or to throw a meaningful exception perhaps). When you initialise your bootstrapper, you can set this Action to perform dependency resolution from the container. So, any time after container initialisation, you can then call this Action from anywhere else in your code and perform container resolution while being insulated form any dependency on the container itself.

So the injection Action might be look something like this:

public static Action<object> InjectProperties;

The bootstrapper might container some code something like this:

Factory.InjectProperties = ContainerExtensions.InjectProperties;

You might also add another level of indirection so that your injection method can be called on any object by adding an extension method to the object type like this:

public static void InjectProperties(this object self)
{
    Factory.InjectProperties(self);
}

And (for example) the UserControl we are injecting dependencies into might then have a parameterless constructor like this:

public MyControl()
{
    this.InjectProperties();
}

In implementing the actual InjectProperties method decisions needs to be made about how to determine which properties the container tries to resolve. One way is to use attributes. You could either define an attribute to flag that a property should be resolved by the container (i.e. an opt-in policy) or you could use the DoNotWire attribute defined in the Castle code base as the basis for an opt-out policy. The following is a simple implementation that would do the job (in this code Container is a static reference to the container itself – this is the only place that you need one apart from the bootstrapper):

public static void InjectProperties(this object self)
{
    if (self == null)
        return;

    var properties = self.GetType().GetProperties();
    foreach (var property in properties)
    {
        if (property.CanWrite == false)
            continue;

        if (property.GetCustomAttributes(typeof(DoNotWireAttribute), true).Length > 0)
            continue;

        if (!Container.HasComponent(property.PropertyType))
            return false; 

        object dependency;
        try
        {
            dependency = Container.Resolve(property.PropertyType);
        }
        catch (Exception e)
        {
            throw new InvalidOperationException("could not resolve component: " + property.PropertyType,e);
        }
        try
        {
            property.SetValue(self, dependency, null);
        }
        catch (Exception e)
        {
            throw new InvalidOperationException("Could not set: " + property, e);
        }
    }
}

This is also a unit test friendly approach as well because you always have the option to override the InjectProperties Action and push mock implementations into the code under test. Or you can just have a unit tests configuration for your container. But successully using mock injection with Castle for unit testing is another post….

jquery hotkeys follow up

Posted in Uncategorized by julianjelfs on July 11, 2009

And I’m pleased to say there is a patched version of the excellent hotkeys plugin now available here. That’s what I call service.

Nasty issue “sort of with” jquery hotkeys plugin

Posted in Javascript, jQuery by julianjelfs on July 8, 2009

I encountered a quite nasty JavaScript issue today. The symptom was that a page that had been working quite happily was suddenly causing IE to crash. After a lot of head scratching I finally tracked it down to the hotkeys jQuery plug-in. I should say up front that there is arguably nothing wrong with the hotkeys plug-in. What the hotkeys plug-in does is to take a copy of jQuery’s own bind function and stores it in a variable called __bind__ on the jQuery object. It then override the bind function with its own in order to extend the functionality for certain event types. If you bind an event that it is not interested in, it delegates the call back to the original jQuery function by calling this.__bind__.

Nothing wrong with that, perfectly sensible and works fine. The problem arises if you accidentally include the script file for the hotkeys plug-in twice. This is not that unlikely if you are writing components that may depend on it and write them such that each component is responsible for its own script registration. This is what I am doing. Ordinarily, duplicate scripts would be filtered out but there was a bug in that code so I ended up with duplicate scripts.

In that case, the second time the script loads,  the following script:

jQuery.fn.__bind__ = jQuery.fn.bind;
It overwrites __bind__ with the already overridden bind function i.e. itself. This has disastrous consequences when the plug-in subsequently calls __bind__ because it enters into an infinite loop and crashes the browser.
Although this only arises if you misuse the hotkeys plug-in, it seems that it could protect itself from this possibility by simply checking to see whether jQuery.fn.__bind__ had already been set before setting it.