Untitled 1
In the past I have used a few IOC containers such as
- Castle
- MEF
Where I work now they are using Unity which is not something I have looked at in
earnest before, so I decided to have a quick look at it, and post a small demo
project. So lets have a look at some samples code shall we. So here are the demo
classes that I will inject/inject into
public class Foo { public int Age { get; set; } } public interface IFooController { void Start(); } public class FooController : IFooController { private readonly Foo foo; public FooController(Foo foo) { this.foo = foo; } public void Start() { Console.WriteLine(string.Format("Foo.Age={0}", foo.Age)); } } public class CompositeFoo { [InjectionConstructor] public CompositeFoo(IEnumerable<IFoo> foos, Func<Foo> fooFactory, Func<Foo, IFooController> fooControllerFactory) { var foo = fooFactory(); var fooController = fooControllerFactory(foo); fooController.Start(); } } public class CompositeFooBase { [InjectionConstructor] public CompositeFooBase(IEnumerable<FooBase> foos) { } } public class CompositeFooBaseArrayCtor { public CompositeFooBaseArrayCtor(FooBase[] foos) { } } public interface IFoo { } public abstract class FooBase { } public class FooI1 : IFoo { } public class FooI2 : IFoo { } public class FooI3 : IFoo { } public class FooB1 : FooBase { } public class FooB2 : FooBase { } public class FooB3 : FooBase { }
That should be enough to give us enough variety to show of a few of the Unity
application blocks tricks, such as
- How to use named instances
- How to resolve single instances
- How to resolve mutiple instances
- How to resolve multiple instances using IEnumerable
- How to pick the constructor to inject
- How to inject a Func
- How to inject a Func and override its own constructor arguments
So those are the areas I have a code sample for, I think the best way it to just
list the code, so without further ado here is the code that demonstrates the
points above:
UnityContainer container = new UnityContainer(); container.RegisterInstance<FooBase>("NonDefaultFooBaseInstanceB1",new FooB1()); container.RegisterInstance<FooBase>("NonDefaultFooBaseInstanceB2", new FooB2()); container.RegisterType<FooBase, FooB1>("NonDefaultFooB1"); container.RegisterType<FooBase, FooB2>("NonDefaultFooB2"); container.RegisterType<IFoo, FooI1>(); container.RegisterType<IFoo, FooI2>("NonDefaultIFoo2"); container.RegisterType<IFoo, FooI3>("NonDefaultIFoo3"); container.RegisterInstance<Foo>("NamedFoo", new Foo() { Age = 23}); container.RegisterType<IFooController, FooController>(); container.RegisterType<Func<Foo>>( new InjectionFactory(c => new Func<Foo>(()=> c.Resolve<Foo>("NamedFoo")))); container.RegisterType<Func<Foo, IFooController>>( new InjectionFactory(c => new Func<Foo, IFooController>( foo => c.Resolve<FooController>(new DependencyOverride<Foo>(foo))))); //can just register this to get around the fact that unity doesn't like IEnumerable in Ctor out of the box container.RegisterType<IEnumerable<IFoo>, IFoo[]>(); container.RegisterType<CompositeFoo>(); container.RegisterType<CompositeFooBase>(); container.RegisterType<CompositeFooBaseArrayCtor>(); var x = container.RegisterType<CompositeFooBase>(new InjectionConstructor(container.ResolveAll<FooBase>())); var fooBases = container.ResolveAll<FooBase>().ToList(); var iFoos = container.ResolveAll<IFoo>().ToList(); var iFoo = container.Resolve<IFoo>(); var iFooNamed = container.Resolve<IFoo>("NonDefaultIFoo2"); var compositeFoo = container.Resolve<CompositeFoo>(); var compositeFooBase = container.Resolve<CompositeFooBase>(); var compositFooBaseArray = container.Resolve<CompositeFooBaseArrayCtor>();
As alawys here is a small demo project so you can try this out for yourself
https://dl.dropboxusercontent.com/u/2600965/Blogposts/2013/UnityTest.zip