DCSIMG
Using Unity Container Hierarchies - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2012 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

Using Unity Container Hierarchies

Using Unity Container Hierarchies

In Unity Application Blocktoday’s post I’m going to explain why and
how to use the Unity container hierarchies.
As the subject suggest Unity application block
supports nested containers and allow you to
build containers hierarchies.

Why to Use Nested Containers 
There are two reasons to use a nested containers:

  • Control the scope of singleton object instances.
  • Register different mapping for specific types.

Controlling the Scope of Singleton Object Instances 
Singleton objects lifetime is managed by the Unity container. They are
kept in scope as long as the container isn’t disposed. In order to enable the
existence of two separate sets of the objects with different lifetime you
use a container hierarchy and manage each set in a different child container
of the parent container. Just remember that if the parent container is disposed
all its children are disposed as well.
The following code demonstrate how to use child containers to manage the lifetime
of a singleton instance:

   IUnityContainer parentContainer = new UnityContainer();

   parentContainer.RegisterType<ILogger, FileLogger>

      (new ContainerControlledLifetimeManager());

   // Create nested child container in parent container

   IUnityContainer childContanier = parentContainer.CreateChildContainer();

   childContanier.RegisterType<Database, SqlDatabase>

      (new ContainerControlledLifetimeManager());

   // Get an instance of type stored in parent container

   ILogger logger = parentContainer.Resolve<ILogger>();

   // Get an instance of type stored in child container

   Database database = childContanier.Resolve<Database>();

   // Dispose child container

   childContanier.Dispose();

 

   // Dispose parent container

   parentContainer.Dispose();

In the example, after the creation of the database object you can either
use it and also use the logger object. After calling the Dispose method on the
child container you will be able to use only the logger object because
disposing the child container will end the lifetime of its generated objects.

Registering Different Mapping For Specific Types
Sometimes we have different dependency injection requirements for specific objects.
For example throughout the running application I want that ILogger will  be resolved
to FileLogger but in some rare situations I need it to be resolved into DatabaseLogger.
In such cases one solution for the problem can be the use of container hierarchies.
You do it by registering the general mapping in the parent container and registering
the specific mapping in the child container. After the registration faze you’ll call the
Resolve method of the relevant container when needed.
So, what is the gain of using this technique instead of only registering the types with
different names and resolving them by name?
We gain the ability to go up the container chain if the registered type isn’t located in
the child container. That means that if calling the Resolve method on the child container
won’t locate the type needed the child container will send the request to the parent
container to be resolved.
The following code is an example for registering of different mapping to specific types:

   IUnityContainer parentContainer = new UnityContainer();

   var child1 = parentContainer.CreateChildContainer();

   var child2 = parentContainer.CreateChildContainer();

   parentContainer.RegisterType<ILogger, FileLogger>

      (new ContainerControlledLifetimeManager());

   child2.RegisterType<ILogger, CustomLogger>

      (new ContainerControlledLifetimeManager());

   // will result in CustomLogger registered in 

   // child2 container

   var logger = child2.Resolve<ILogger>();

   logger.Log("Test");

   // will result in the FileLogger registered in the

   // parent container

   var logger2 = child1.Resolve<ILogger>();

   logger.Log("Test");

Summary
To sum up the post, the container hierarchy feature is very useful in the
following situations - control the scope of singleton object instances and
register different mapping for specific types. I showed examples of how
to use the container hierarchies in every one of these situations.


Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# July 26, 2008 6:15 AM

Rotem Bloom said:

גיל,

אני רואה שאתה כותב לא מעט על Unity אתה יכול לספר כמה באמת אתה משתמש בזה והאם זה באמת עוזר לך בפרוייקטים שעשית?

# July 27, 2008 11:20 AM

Gil Fink said:

Hi Rotem,

First, because Unity is a new application block I only used it in a small amount of projects. Eventhough, this application block enables to loosy couple main issues in the application you build (by levaraging dependency injection). It is most useful in situation such as injecting infra structure objects (loggers, data access, validators etc) or building a plugable architecture. Because of that it's one of the new building blocks of Enterprise Library 4.0 instead of the old ObjectBuilder subsystem. To sum up the block is very helpful.  

# July 27, 2008 1:04 PM