Unity Messabout





0/5 (0 vote)
Unity messabout
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 let's take a look at some sample 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 off a few of the Unity application blocks tricks, such as:
- How to use named instances
- How to resolve single instances
- How to resolve multiple 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 is 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 always, here is a small demo project so you can try this out for yourself: