65.9K
CodeProject is changing. Read more.
Home

Unity Messabout

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0 vote)

Mar 5, 2014

CPOL
viewsIcon

12601

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:

  1. How to use named instances
  2. How to resolve single instances
  3. How to resolve multiple instances
  4. How to resolve multiple instances using IEnumerable
  5. How to pick the constructor to inject
  6. How to inject a Func
  7. 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: