Ramakant Yadav the Internet edition

Random Ramblings Of Ramakant Yadav

15 Jun 2011



Onany non-trivial .NET application, Dependency Injection is almost mandatory. Although Unity does dependency injection rather well, everyone seems to have their own preferences. For most people working in corporations, however, Unity is the only way.

Dependency injection can be divided into 4 types: type, constructor, property and methods. A dependency injection container is supposed to provide the following functionality:

1. Provide a method for registering of mapping of interfaces to concrete implementations. This mapping is used when an object is to be created.
2. Provide a method for the resolving of the above mapping at runtime. Typically a resolve method that takes in the interface and returns the instance of an object.
3. Provide some mechanism for controlling the kind of object created on every call of resolve. Some application might require a singleton to be created, other applications may require a weak reference to be used or maybe a different object for each thread.

Most of them also provide a mechanism for resolution of dependency chains. That is useful when a hierarchy of objects need to be created.

Dependency containers typically provide two ways of configuring[mapping the interface to the concrete implementation]. The first way is to do it at design time using the XML configuration file.

Alternatively, one may chose to do configuration at runtime by using the configuration classes.

Here is how to do the configuration at design time in unity[based upon msdn]. All one needs to specify is the name of the container, the mapping[from the type to the concrete implementation], and the lifetime setup.

	  	<containers>
		<container name = "SampleContainer">
	  	<type type="Custom.MyBaseClass" mapTo="Custom.MyConcreteClass">
          	<lifetime type="singleton" /> 
		</container>
		</containers>
In Unity 2.0, the register type is used instead of the type type like the following
		<container>
		<register type="Custom.MyBaseClass" name = "SampleContainer" mapto="Custom.MyConcreteClass" />
		</container>

The "singleton" is defined as a type alias using this[In unity 2.0, it is no longer typeAlias, it is just alias] :
  		<TypeAlias alias="singleton"
         	type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
               	Microsoft.Practices.Unity" />
The unity application block does not automatically load all the above mappings[unlike other xml based DI containers]. To load the SampleContainer configured above, one needs to use the code similar to the following :

		IUnityContainer container = new UnityContainer();	//Create a container
		UnityConfigurationSection section 
			  = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");//get the relevent section from XML
		section.Containers["SampleContainer"].Configure(container); //Configure the container.
or use the LoadConfiguration extension method in unity 2.0 as follows:
		
		IUnityContainer container = new UnityContainer().LoadConfiguration(section).LoadConfiguration(section,"SampleContainer");

There are breaking changes between version 2.0 and the earlier versions.

The thing to remember is that all containers are at the same level in the configuration file. To create a hierarchy, one needs to create childContainers using the CreateChildContainer method.

		IUnityContainer container = new UnityContainer();//the parent container
		IUnityContainer childContainer = container.CreateChildContainer();//The child container created from the parent.
The section will need to be extracted from the file and configuration done exactly as before.

After this, a simple call to container.Resolve will return the object needed.

However, some people may not like to do xml configuration. Even though it means that there is no need to touch the C# code. The reasons for this being increase in complexity. Since the xml files need to be edited manually, there is chance of making mistakes. So in unity 2.0, there is support for visual studio intellisense. All we need it to include the xmlns like the following just before the alias:
	 
If one prefers to work the container without the use of xml configuration files, one may use the following code
	IUnityContainer myContainer = new UnityContainer() 
   					.AddNewExtension() 
   					.Configure() 
       					.AddPolicy("PolicyName") 
           				.AddMatchingRule() 
           				.AddCallHandler() 
       					.Container; 


The above is made possible due to the fluent interface of Unity container's API. To generate a singleton object one may need to use the following code
		myContainer1.RegisterType() ; //is used for types.
		myContainer1.RegisterType(new InjectionConstructor(12,'erew'));//injects constructor
		myContainer2.RegisterType("SampleMapping") ; //creates a named mapping
                myContainer3.RegisterType("SampleMapping",new ContainerControlledLifeTimeManager);//for singleton
		myContainer3.ResolveType();//will create a singleton object and container will manage lifetime.


blog comments powered by Disqus


The Archives | Contact me | Home


All Rights Reserved ramakantyadav.com