Property injection with Autofac

using PostSharp’s LocationInterceptionAspect


A little while ago I was setting up a new solution for a project. As I am very fond of a SOLID design and a big supporter to see what can be improved every new project I am starting, I dived into the world of Dependency Injection (DI) frameworks.

It is really hard to find one that fits your needs because there are a lot and the differences are not very large. Scott Hanselman wrote a blog post on them a while back, and most of them are still out there. Ninject, Unity, Autofac, StructureMap, Castle Windsor are generally used. I ultimately chose for Autofac because of the multitenancy which I was looking for.


When using a DI framework, you’ll notice there are several ways to inject your registered objects. One of them is property (setter) injection. In a few frameworks this can be done with an attribute. In Ninject, for example, this looks something like this:

[Inject]
public IWeapon Weapon { get; set; }

To achieve this in Autofac, you have to tell your registered objects that you’ll probably want to resolve some properties within the object. This means that you’ll have to do this for all your registered objects.

builder.RegisterType<Weapon>().As<IWeapon>().PropertiesAutowired();

In my opinion the attribute is a cleaner solution. It should not be the concern of the container whether or not I want to inject other objects.

That is why I searched for a solution which I found in PostSharp, which is a Design Pattern Automation tool.

“PostSharp is a tool that allows development teams to achieve more with less code in Microsoft .NET”

… and that is exactly what I want to achieve. Therefore I wrote a custom AutofacResolveAttribute which will return the correct service from the current DependencyResolver.

[Serializable]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class AutofacResolveAttribute : LocationInterceptionAspect
{
public override void OnGetValue(LocationInterceptionArgs args)
{
args.ProceedGetValue();
if (!args.Location.LocationType.IsInterface) return;
        if ( args.Value != null )
{
args.Value = DependencyResolver.Current.GetService(args.Location.LocationType);
args.ProceedSetValue();
}
}
}

In the code snippet you can see the OnGetValue method which will be invoked when you get your property. There is also a check if the property you are trying to get is a interface, which you can remove if you like.


I know this isn’t a structual way of solving this but it may help you for your current problems. I’m hoping Autofac will include a similar functionality in a future release. If this blogpost helped you, please upvote my answer on Stack Overflow.