Unity

Unity (MVC Example)

“The Unity Container (Unity) is a lightweight, extensible dependency injection container. It facilitates building loosely coupled applications”

This was very simple to setup for an ASP.NET MVC project (net461) using the nuget packages:

  • Unity.Container, Version=5.7.0
  • Unity.Abstractions, Version=3.3.0
  • Unity.Mvc, Version=5.0.13

Implementation is as simple as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
~ /App_Start/UnityConfig.cs
public static void RegisterComponents()
{
var container = new UnityContainer();

// resolve instances with parameterless constructors
container.RegisterType<IFizzRepository, FizzRepository>();
container.RegisterType<IBuzzRepository, BuzzRepository>();

// resolve instances with constructors dependant on something already in the container
container.RegisterType<IFooService, FooService>(
new InjectionConstructor(
container.Resolve<IFizzRepository>(),
container.Resolve<IBuzzRepository>()
));

DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

~/Global.asax.cs
UnityConfig.RegisterComponents();

~/Controllers/KiefController.cs
Constructor signature can then include `IFizzRepository fizzRepository, IFooService fooService`

Modules

If you have worked with amazing Dependency Injection Frameworks such as Autofac or Ninject you would expect to be able to create cohesive modules right? Well Unity doesn’t support this out of the box however you can create extension methods that do pretty much the same thing, just remember the order will matter if you are going to be calling container.Resolve later down the stack.

Simply call container.AddExtension and new up the module:

1
2
3
4
5
6
7
8
9
~ /App_Start/UnityConfig.cs
public static void RegisterComponents()
{
var container = new UnityContainer();

// Data repository
container.AddExtension(new RepositoryModule());

....

The module then inherits the Container from the base class UnityContainerExtension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using Unity;
using Unity.Extension;

namespace FooApp.Domain.Plumbing.Unity
{
public class RepositoryModule : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IFizzRepository, FizzRepository>();
Container.RegisterType<IBuzzRepository, BuzzRepository>();
}
}
}

Abstract Factory

Unity is unable to automatically resolve IEnumerable<T> dependencies which you could use with an Abstract Factory.

You can however get around this by naming the dependency.

1
2
Container.RegisterType<IPriceRule, EachPriceRule>("EachPriceRule");
Container.RegisterType<IPriceRule, WeightPriceRule>("WeightPriceRule");

This is then automagically injected into the consumer.

1
2
3
4
5
6
7
8
9
public class FooController : Controller
{
private readonly IEnumerable<IPriceRule> _priceRules;

public FooController(IEnumerable<IPriceRule> priceRules)
{
_priceRules = priceRules;
}
}

References