Using Unity Container Hierarchies

July 26, 2008

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.



Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

2 comments

  1. Rotem BloomJuly 27, 2008 ב 11:20

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

    Reply
  2. Gil FinkJuly 27, 2008 ב 13:04

    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.

    Reply