The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection.
Implementing the Dependency Injection with Unity Container
According to MSDN
The Unity Container (Unity) is a lightweight, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages:
- Simplified object creation, especially for hierarchical object structures and dependencies
- Abstraction of requirements; this allows developers to specify dependencies at run time or in configuration and simplify
- Increased flexibility by deferring component configuration to the container
- Service location capability; this allows clients to store or cache the container
- Instance and type interception
Note: Here are we are dealing with a simple implementation of Unity Container. You can use Unity Container for maintaining the object's lifetime by specifying that the object will work as a singleton that serves all the requests or per call and many other things. You are advised to go through MSDN for more details.
Setter Injector using Unity
So, here is my code to implement the Unity Container:
static void Main(string[] args)
{
IClassA classA = new ClassA();//creating instance of class A IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IClassB, ClassB>();
var classB = unityContainer.Resolve<IClassB>();
//assign the instance to the classB property of class A classA.ClassB = classB;
//Call the method classA.DoSomethingFromClassB();
Console.Read();
}
First we are creating an instance of Unity Container
IUnityContainer unityContainer = new UnityContainer();
Then we are registering the interfaces and their concrete classes
Then we are registering the interfaces and their concrete classes
unityContainer.RegisterType<IClassB, ClassB>();
Now asking the Container to resolve to get the actual instance of the concrete class
var classB = unityContainer.Resolve<IClassB>();
But
the Unity Container can intelligently identify what dependency object
should be created if you specify the attribute [Dependency] in the
consuming class setter methods.You can see it in practice as below
I am modifying the code to test it.
public class ClassA : IClassA {
private IClassB _classB;
[Dependency]
public IClassB ClassB
{
get { return _classB; }
set {
if (value == null) throw new ArgumentNullException("value");
_classB = value;
}
}
public void DoSomethingFromClassB()
{
_classB.DoSomething();
}
}
Now my Program class looks as in the following:
static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IClassB, ClassB>();
IClassA classA = new ClassA();//creating instance of class A var instance = unityContainer.Resolve<ClassA>();
//Call the method instance.DoSomethingFromClassB();
Console.Read();
}
If you observe in the preceding code I specified the attribute [Dependency] above the public propery of the class A and in the Main method, I have created the instance of Class A and it is asking Unity to resolve all its dependencies so that I do not need to explicitly create the dependent objects.
var instance = unityContainer.Resolve<ClassA>();
Constructor Injector using Unity
To implement this, I have changed my interface as below:
public interface IClassA {
//IClassB ClassB { get; set; } void DoSomethingFromClassB();
}
Now the classA looks as in the following:
public class ClassA : IClassA {
private readonly IClassB _classB;
[InjectionConstructor]
public ClassA(IClassB classB)
{
_classB = classB;
}
public void DoSomethingFromClassB()
{
_classB.DoSomething();
}
}
Observe the attribute [InjectionConstructor]. This tells the Unity that the ClassA is dependent on an object which is to be injected in a constructor.
Now the Main program looks as in the following
static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IClassB, ClassB>();
var instance = unityContainer.Resolve<ClassA>();
instance.DoSomethingFromClassB();
Console.Read();
}
Here I am just specifying that we need to create an instance of ClassA by resolving all its dependencies i.e. dependent objects should be resolved by the Unity Container.
var instance = unityContainer.Resolve<ClassA>();
Method Injector using Unity Container
In this, we are going to inject the dependency using a method in a class. In our example ClassA has a method that takes IClassB type as a parameter. Using a Unity Container we are going to inject the dependency into the class ClassA. In the classA, we are going to decorate the method with the attribute [InjectionMethod].
public interface IClassA {
void DoSomethingFromClassB();
void SetClassB(IClassB classB);
} public class ClassA : IClassA {
private IClassB _classB;
[InjectionMethod]
public void SetClassB(IClassB classB)
{
_classB = classB;
}
public void DoSomethingFromClassB()
{
_classB.DoSomething();
}
} static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IClassB, ClassB>();
var instance = unityContainer.Resolve<ClassA>();
instance.DoSomethingFromClassB();
Console.Read();
}
In
the preceding example, we are registering the classes that Unity is
supposed to resolve dynamically by reading the attributes of the class.
Here, the unity container without explicitly specifying the details of
ClassA reads all the attributes in ClassA and resolves all the
dependencies in the ClassA by instantiating the dependent objects and
injecting them.
Method Injector using Unity Container
In this, we are going to inject the dependency using a method in a class. In our example ClassA has a method that takes IClassB type as a parameter. Using a Unity Container we are going to inject the dependency into the class ClassA. In the classA, we are going to decorate the method with the attribute [InjectionMethod].
public interface IClassA {
void DoSomethingFromClassB();
void SetClassB(IClassB classB);
} public class ClassA : IClassA {
private IClassB _classB;
[InjectionMethod]
public void SetClassB(IClassB classB)
{
_classB = classB;
}
public void DoSomethingFromClassB()
{
_classB.DoSomething();
}
} static void Main(string[] args)
{
IUnityContainer unityContainer = new UnityContainer();
unityContainer.RegisterType<IClassB, ClassB>();
var instance = unityContainer.Resolve<ClassA>();
instance.DoSomethingFromClassB();
Console.Read();
}
No comments:
Post a Comment