I’ve been using Unity as the DI container in a client project. I like the ability to configure the container at runtime, and I like the fluent mapping registration interface, but I don’t like how intimate I need to be with the Unity design to do things. For instance, configuring the container to support a decorator or chain object pattern requires some non-intuitive container configuration code.
For instance, consider this simple object graph:
1 public interface IContract
2 {
3 }
4
5 public class Contract : IContract
6 {
7 }
8
9 public class ContractDecorator : IContract
10 {
11 public IContract Base { get; set; }
12
13 public ContractDecorator(IContract @base)
14 {
15 Base = @base;
16 }
17 }
The IContract interface defines the contract, which is empty in this case for simplicity. The Contract class defines a concrete implementation, and the ContractDecorator is a decorating object that needs an IContract implementation during initialization.
My intent is to register this relationship in my IoC container, so when I ask for an IContract, I get a Contract instance wrapped in a ContractDecorator instance. In short, the same result as this code:
1 var contract = new ContractDecorator(
2 new Contract()
3 );
If this were Castle Windsor, it would be easy to do:
1 var container = new WindsorContainer();
2 var kernel = container.Kernel;
3 // ...
4 kernel.AddComponent<IContract, ContractDecorator>();
5 kernel.AddComponent<IContract, Contract>();
Castle allows me to stack my type mappings using a simple convention: during the object graph buildup, dependencies of type IContract resolve using the next type mapping added to the component stack. In this case when I ask Castle for an IContract, I end up getting a ContractDecorator instance initialized with a Contract instance. It just works, the way I expect it to.
Unity is not so just-worky-the-way-I-expecty in this case. In fact, making this work can be pretty esoteric. I attempted something based on an example from David Hayden (see this):
1 var container = new UnityContainer();
2 container.RegisterType(
3 typeof( IContract ),
4 typeof( Contract ),
5 "Contract"
6 );
7 contract.RegisterType(
8 typeof( IContract ),
9 typeof( ContractDecorator ),
10 new InjectionConstructor(
11 new ResolvedParameter(
12 typeof( IContract ),
13 "Contract"
14 )
15 )
16 );
17 var contract = container.Resolve<IContract>();
I think this code is obtuse, and having to use a magic string feels fragile. Much of it is there only to support Unity’s internal model, not my object model, and I’m not terribly interested in Unity’s internal model. I use this object pattern quite a bit, and I’d rather Unity support a simple convention the way Castle Windsor does – so I coded up a Unity Container Extension to make it happen.
The Container Extension
Here is the container extension code:
1 public class DecoratorContainerExtension
2 : UnityContainerExtension
3 {
4 private Dictionary<Type, List<Type>> _typeStacks;
5 protected override void Initialize()
6 {
7 _typeStacks = new Dictionary<Type, List<Type>>();
8 Context.Registering += AddRegistration;
9
10 Context.Strategies.Add(
11 new DecoratorBuildStrategy(_typeStacks),
12 UnityBuildStage.PreCreation
13 );
14 }
15
16 private void AddRegistration(
17 object sender,
18 RegisterEventArgs e)
19 {
20 if (!e.TypeFrom.IsInterface)
21 {
22 return;
23 }
24
25 List<Type> stack = null;
26 if (!_typeStacks.ContainsKey(e.TypeFrom))
27 {
28 stack = new List<Type>();
29 _typeStacks.Add(e.TypeFrom, stack);
30 }
31 else
32 {
33 stack = _typeStacks[e.TypeFrom];
34 }
35
36 stack.Add(e.TypeTo);
37 }
38 }
The container extension does two things:
- It tracks type registrations for interfaces, building up an ordered list of types that have been registered to each interface (lines 20-36).
- It initializes a new DecoratorBuildStrategy and adds it to the chain of build-up strategies (lines 10-13).
The Build Strategy
The build strategy is where the magic happens:
1 public class DecoratorBuildStrategy : BuilderStrategy
2 {
3 private readonly Dictionary<Type, List<Type>> _typeStacks;
4
5 public DecoratorBuildStrategy(
6 Dictionary<Type, List<Type>> typeStacks
7 )
8 {
9 _typeStacks = typeStacks;
10 }
11
12 public override void PreBuildUp(IBuilderContext context)
13 {
14 var key = context.OriginalBuildKey;
15
16 if (!(key.Type.IsInterface &&
17 _typeStacks.ContainsKey(key.Type)))
18 {
19 return;
20 }
21
22 if (null != context.GetOverriddenResolver(key.Type))
23 {
24 return;
25 }
26
27 Stack<Type> stack = new Stack<Type>(
28 _typeStacks[key.Type]
29 );
30
31 object value = null;
32 stack.ForEach(
33 t =>{
34 value = context.NewBuildUp(
35 new NamedTypeBuildKey(t, key.Name)
36 );
37 var overrides = new DependencyOverride(
38 key.Type,
39 value
40 );
41 context.AddResolverOverrides(overrides);
42 }
43 );
44
45 context.Existing = value;
46 context.BuildComplete = true;
47 }
48 }
The build strategy’s PreBuildUp method uses the type lists from the container extension to iteratively build up instances of the interface (lines 32-43). In each iteration of build-up, a DependencyOverride redefines the object used to resolve the interface type (lines 37-41). In effect, this “walks the type stack” associated with the interface, allowing the least-dependent implementation to be created first, then injected into the next least-dependent implementation, and so on.
The algorithm makes use of the Unity IoC to resolve dependencies during each step of the “type stack walk” (the NewBuildUp method call on line 34). This means that each object type in the stack will be constructed using the same IoC context, so additional dependencies will be available to them during creation. It also means that this build strategy is recursive, so special care must be taken to prevent stack smashing – line 22 checks if the DependencyOverride is in effect for the interface type, skipping the “type stack walk” and short-circuiting an endless recursive call chain.
The Extension in Use
This is where things get easy – simply add the DecoratorContainerExtension to the UnityContainer, and then you can use the same convention available in the Castle Windsor container:
1 [Fact]
2 public void CreatesTheMostDependentType()
3 {
4 var c = new UnityContainer()
5 .AddExtension(new DecoratorContainerExtension())
6 .RegisterType<IContract, ContractDecorator>()
7 .RegisterType<IContract, Contract>();
8
9 var o = c.Resolve<IContract>();
10 Assert.NotNull(o);
11 Assert.IsType(typeof(ContractDecorator), o);
12 Assert.IsType(
13 typeof(Contract),
14 ((ContractDecorator)o).Base
15 );
16 }
This is simple, it’s less code, and most importantly it describes my intent better. And it’s focused on my object model and not Unity’s, so I can create arbitrarily complex decorator chains without any fuss. I’m fairly happy with it.
Enjoy!