Dependency Injection Semantics

An entry about inversion of control Publication date 4. May 2009 16:21

So you’ve decided to follow the dependency inversion principle, and have your dependencies injected (maybe by some container). Surely whether you use constructor or setter injection is a matter of personal choice, yes?

I don't think so.

Consider the restriction that a constructor argument imposes on the creation of your class – the argument is implicitly a required dependency because you can’t make your code compile if you can’t provide it (well sure, you can pass in a null value, but then you’re explicit about it). Property setters on the other hand, carry no such implications. And this is important to recognize and take advantage of, because code which carries obvious, unambiguous semantics is much, much easier to work with.

Update: To clarify, my recommendation is that you always prefer constructor injection for required dependencies, and only consider using property injection for optional dependencies.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Constructor Injection for ASP.NET MVC Model Binders

An entry about asp.net mvc | inversion of control Publication date 18. April 2009 13:23

My last post was about how to let your IOC container manage ASP.NET MVC action filters. This time, let’s look at how to do the same with model binders.

Last month, Jimmy Bogard shared his SmartBinder implementation which solved this. For my requirements however, Jimmy’s implementation has one show-stopper: By injecting all the model binders into his custom binder resolver, he is essentially limiting the lifetime of binders to singleton behavior, since the resolver itself has to live as a singleton within ASP.NET MVC’s model binder dictionary. I think that a better solution would be to let the custom binder resolver forward binder resolution to the IOC container on an ad-hock basis. Here’s my GenericBinderResolver which does that:

public class GenericBinderResolver : DefaultModelBinder

{

    private readonly ICanResolveDependencies _resolver;

    private static readonly Type BinderType = typeof(ModelBinder<>);

 

    public GenericBinderResolver(ICanResolveDependencies resolver)

    {

        _resolver = resolver;

    }

 

    public override object BindModel(ControllerContext controllerContext,
                                     ModelBindingContext bindingContext)

    {

        Type genericBinderType = BinderType.MakeGenericType(bindingContext.ModelType);

 

        var binder = _resolver.Resolve(genericBinderType) as IModelBinder;

 

        if (null != binder) return binder.BindModel(controllerContext, bindingContext);

 

        return base.BindModel(controllerContext, bindingContext);

    }

}

Notice how the binder resolver builds a generic ModelBinder<T> type from the model type, and asks the IOC container to resolve it (the container is abstracted by the ICanResolveDependencies interface). This way, the container is free to manage the lifetime of each model binder separately.

Binders are implemented by deriving from my generic ModelBinder<T> class:

public abstract class ModelBinder<T> : IModelBinder

{

    protected abstract T BindModel(ControllerContext controllerContext,
                                   ModelBindingContext bindingContext);

 

    object IModelBinder.BindModel(ControllerContext controllerContext, 
                                  ModelBindingContext bindingContext)

    {

        return BindModel(controllerContext, bindingContext);

    }

}

For example, here’s a model binder which gets an aggregate root from a domain service. This binder has to have a lifetime which is compatible with the per-request scope of the domain service it depends upon (note: I’ve simplified the binder a bit, removing validation etc).

public class PostModelBinder : ModelBinder<IPost>

{

    private readonly IBlogService _blogService;

 

    public PostModelBinder(IBlogService blogService)

    {

        _blogService = blogService;

    }

 

    protected override IPost BindModel(ControllerContext controllerContext,
                                       ModelBindingContext
bindingContext)

    {

        var request = controllerContext.HttpContext.Request;

 

        var postIdString = request["postId"];

 

        IPost post = null;

 

        if (!String.IsNullOrEmpty(postIdString))

        {

            var postId = Int32.Parse(postIdString);

            post = _blogService.FindPost(postId);

        }

 

        return post;

    }

}

Then, all I have to do is register the binder in my container (Ninject):

Bind<ModelBinder<IPost>>().To<PostModelBinder>().Using<RequestScopedBehavior>();

Currently rated 4.2 by 5 people

  • Currently 4.2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Constructor Injection for ASP.NET MVC Action Filters

An entry about asp.net mvc | inversion of control Publication date 9. April 2009 11:50

ASP.NET MVC’s action filters allow you to execute some code before/after an action in a declarative manner, manipulating what goes into or comes out of the action. In essence, they are what’s called aspects in Aspect Oriented Programming; a way of encapsulating crosscutting concerns into reusable components. For example, instead of this:

public ActionResult SomeActionWhichRequiresAuthentication()

{

    if (!User.Identity.IsAuthenticated)

    {

        return RedirectToAction("Login", "Authentication");

    }

    else

    {

        // ...

    }

}

You’ll do this:

[Authorize]

public ActionResult SomeActionWhichRequiresAuthentication()

{

    // ...

}

However, a problem with ASP.NET MVC’s action filters is that there’s no support for having an IOC container manage them, which means that if I need to do something more complicated that requires calling into a domain service/repository for example, I cannot get these injected easily. Jeremy Skinner has a solution which enables property injection, but what I really want is constructor injection.

Solution: The Proxy Pattern

What I came up with, was to build a filter proxy. Using it looks like this:

[Filter(typeof(AuthorizationFilter))]

public ActionResult SomeActionWhichRequiresAuthentication()

{

    // ...

}

Internally, the FilterAttribute resolves the actual filter using the IOC container and forwards all its calls to it:

public class FilterAttribute : ActionFilterAttribute

{

    private readonly Type _actionFilterType;

    private IActionFilter _action;

 

    public FilterAttribute(Type actionFilterType)

    {

        _actionFilterType = actionFilterType;

    }

 

    public override void OnActionExecuting(ActionExecutingContext filterContext)

    {

        // resolve the action filter using the IOC container

        var container = (ICanResolveDependencies) HttpContext.Current.ApplicationInstance;

        _action = (IActionFilter)container.Resolve(_actionFilterType);

 

        _action.OnActionExecuting(filterContext);

        base.OnActionExecuting(filterContext);

    }

 

    public override void OnActionExecuted(ActionExecutedContext filterContext)

    {

        _action.OnActionExecuted(filterContext);

        base.OnActionExecuted(filterContext);

    }

}

This allows the IOC container to manage the instantiation and lifetime of the action filter. Note the assumption that the applications Application object (Global.asax) implements the ICanResolveDependencies interface, which essentially is an abstraction of the IOC container.

Currently rated 3.3 by 3 people

  • Currently 3.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Dependency Trouble

An entry about agile | inversion of control Publication date 3. April 2009 08:37

Imagine two teams, A and B, both working on the same piece of software. How do you solve the problem arising from team A having a work item X which they cannot implement because it requires something that team B are working on to be done first?

Whenever a dependency is obstructing progress, you probably have a missing or leaky abstraction.

Take a step back and consider the boundaries of what you are trying to achieve. Team A shouldn't really care how team B solves X. So let them pretend that it has been solved! The accept criteria for their task should be independent of team B's efforts anyways; the tests that team A come up with for their task should be executed in isolation - in other words under the assumption that everything else works. I've written about this at a lower level before - the same principle of dependency inversion applies here.

Of course, later when both team A and team B are done, they merge their work into an integration branch where integration testing etc happens.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Ninject and Singletons: How To Ensure One Instance per Variation of Activation Parameters

An entry about inversion of control Publication date 10. October 2008 18:09

Working on a pet project (that I hopefully will be able to unveil soon) which uses Ninject as its Inversion of Control container, I came upon a need to ensure that there only ever existed a single instance of a type, per variation of transient parameters in the activation context. An example will help clarify…

Say for instance that you have a class like this:

public class Test
{
    private static int InstanceCount = 0;
 
    public Test(string param)
    {
        InstanceId = ++InstanceCount;
    }
 
    public int InstanceId;
}

 

Now, assume we execute the following code:

var test1 = kernel.Get<Test>(With.Parameters.ConstructorArgument("param", "1"));
var test2 = kernel.Get<Test>(With.Parameters.ConstructorArgument("param", "2"));
var test3 = kernel.Get<Test>(With.Parameters.ConstructorArgument("param", "1"));
 
Console.WriteLine(test1.InstanceId);
Console.WriteLine(test2.InstanceId);
Console.WriteLine(test3.InstanceId);
Console.ReadLine();

 

What I want to happen here, is for the kernel to create two instances of my Test class, so that test1 and test2 test3 are the same because they passed the same transient parameter to the activation context. The output of the app then should be:

1
2
1

Notice that the first and third lines indicate that those two objects are the same instance. How can we make this happen? By creating the following binding for our Test class:

Bind<Test>().ToSelf().Using<SingletonPerVariationOfParametersBehavior>())

 

The SingletonPerVariationOfParametersBehavior (f you have an idea for a shorter name that still explains what it does let me know!) class is a custom behavior, which thanks to the great API that Ninject has only took like 10 minutes to implement. It looks like this:

/// <summary>
/// A behavior which ensures a single instance of a type exist, per variation of 
/// transient parameters in the activation context, throughout the application.
/// The variation is determined by combining the hashcodes of the implementation 
/// type and the hashcodes of transient parameter values.
/// </summary>
public class SingletonPerVariationOfParametersBehavior : BehaviorBase
{
    /// <summary>
    /// Initializes a new instance of the 
    /// <see cref="SingletonPerVariationOfParametersBehavior"/> class.
    /// </summary>
    public SingletonPerVariationOfParametersBehavior()
    {
        SupportsEagerActivation = false;
        ShouldTrackInstances = true;
    }
 
    private readonly Dictionary<int, IContext> _contextCache = new Dictionary<int, IContext>();
 
    ///<summary>
    ///Resolves an instance of the type based on the rules of the behavior.
    ///</summary>
    ///<param name="context">The activation context.</param>
    ///<returns>
    ///An instance of the type associated with the behavior.
    ///</returns>
    public override object Resolve(IContext context)
    {
        Ensure.NotDisposed(this);
 
        int hash = BuildHashForContext(context);
 
        IContext cachedContext;
 
        if (!_contextCache.TryGetValue(hash, out cachedContext))
        {
            lock (_contextCache)
            {
                if (!_contextCache.TryGetValue(hash, out cachedContext))
                {
                    context.Binding.Components.Get<IActivator>().Activate(context);
                    _contextCache.Add(hash, context);
                    cachedContext = context;
                }
            }
        }
 
        return cachedContext.Instance;
    }
 
    /// <summary>
    /// Builds a unique hash code for the context based on the implementation 
    /// type plus the transient activation parameters
    /// </summary>
    /// <param name="context">The activation context</param>
    private static int BuildHashForContext(IContext context)
    {
        int hashCode = context.Implementation.GetType().GetHashCode();
 
        foreach (Type type in context.Parameters.GetTypes())
        {
            foreach (IParameter param in context.Parameters.GetAll(type))
            {
                object value = param.GetValue(context);
 
                if (null != value) hashCode = hashCode ^ value.GetHashCode();
            }
        }
 
        return hashCode;
    }
 
    ///<summary>
    /// Releases the instance of the type contained in the context based 
    /// on the rules of the behavior.
    ///</summary>
    ///<param name="context">The activation context.</param>
    public override void Release(IContext context)
    { }
 
    ///<summary>
    /// Releases all resources held by the object.
    ///</summary>
    ///<param name="disposing"><see langword="True" /> if managed objects 
    /// should be disposed, otherwise <see langword="false" />.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && !IsDisposed)
        {
            DestroyAll(_contextCache.Values);
            _contextCache.Clear();
        }
 
        base.Dispose(disposing);
    }
}

 

Disclaimer: Don’t trust me to have written this code without any bugs or performance bottlenecks - it’s fresh out of the oven.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Determining if a Conditional Binding is Resolvable With Ninject

An entry about inversion of control Publication date 12. September 2008 21:05

While working on an ASP.NET MVC application today which uses the Ninject IOC container, I came across a scenario in which I needed a way to figure out whether a given conditional binding would be resolvable or not. Out of the box, the only way to really do this would be to call Get<T>() and catch the ActivationException thrown. Not a very elegant solution, especially since it has the potentially nasty side-effect of actually activating the instance of the binding if it was found.

So I set out to find a better way, and with a few pointers from Nate (the author of Ninject), I ended up with the following extension method for IKernel:

public static class KernelExtensions
{ 
    /// <summary>
    /// Determines whether a given type has a resolvable binding
    /// </summary>
    public static bool HasBindingFor<T>(this IKernel kernel, IParameterCollection parameters)
    {
        Type service = typeof (T);
 
        // build a context with the parameters
        IContext context = kernel.Components.Get<IContextFactory>().Create(service);
        context.Parameters = parameters;
 
        // find all the bindings for the type
        var registry = kernel.Components.Get<IBindingRegistry>();
        ICollection<IBinding> bindings = registry.GetBindings(service);
 
        bool result = bindings.Has(binding => binding.Condition.Matches(context));
        return result;
    }
}

In my ASP.NET MVC application I can now use this to for example determine whether a given controller exists or not:

bool controllerExists = _kernel.HasBindingFor<IController>(
With.Parameters.Variable("controllerName", controllerName));

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS