The unity container manages the lifetime of objects of all the dependencies that it resolves using lifetime managers.
Unity container includes different lifetime managers for different purposes. You can specify lifetime manager in RegisterType() method at the time of registering type-mapping.
Lifetime Manager
Description
TransientLifetimeManager
When no lifetime manager is defined, unity defaults to Transient.
Creates a new object of requested type every time you call Resolve or ResolveAll method.
ContainerControlledLifetimeManager
Creates a singleton object first time you call Resolve or ResolveAll method and then returns the same object on subsequent Resolve or ResolveAll call.
HierarchicalLifetimeManager
Same as ContainerControlledLifetimeManager, the only difference is that child container can create its own singleton object. Parent and child container do not share singleton object.
PerResolveLifetimeManager
Similar to TransientLifetimeManager but it reuses the same object of registered type in the recursive object graph.
PerThreadLifetimeManager
Creates singleton object per thread basis. It returns different objects from the container on different threads.
ExternallyControlledLifetimeManager
It manintains only weak reference of objects it creates when you call Resolve or ResolveAll method. It does not maintain the lifetime of strong objects it creates and allow you or garbage collector to control the lifetime. It enables you to create your own custom lifetime manager
When trying to use Dependency Injection with Web API 2 I encountered a problem because the application doesn't create the controller directly. Web API creates the controller when it routes the request, and Web API doesn't know anything about your dependencies ie AppLogger
So basically your dependencies will not be initialised on creation of the controller.
This is where the Web API dependency resolver comes in.
The Web API Dependency Resolver
Web API defines the IDependencyResolver interface for resolving dependencies.
The IDependencyResolver method inherits IDependencyScope and adds the BeginScope method.
So basically the minimum requirement is that the 3 of these methods are implemented.
When Web API creates a controller instance, it first calls IDependencyResolver.GetService, passing in the controller type. You can use this extensibility hook to create the controller, resolving any dependencies. If GetService returns null, Web API looks for a parameterless constructor on the controller class.
Dependency Resolution with the Unity Container
The interface is really designed to act as bridge between Web API and existing IoC containers.
Here is an implementation of IDependencyResolver that wraps a Unity container.
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable
Configuring the Dependency Resolver
Set the dependency resolver on the DependencyResolver property of the global HttpConfiguration object.
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
// Other Web API configuration not shown.
}
Dependency Scope and Controller Lifetime
Controllers are created per request. To manage object lifetimes, IDependencyResolver uses the concept of a scope.
The dependency resolver attached to the HttpConfiguration object has global scope. When Web API creates a controller, it calls BeginScope. This method returns an IDependencyScope that represents a child scope.
Web API then calls GetService on the child scope to create the controller. When request is complete, Web API calls Dispose on the child scope. Use the Dispose method to dispose of the controller's dependencies.
How you implement BeginScope depends on the IoC container. For Unity, scope corresponds to a child container:
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}