In this post we will see 2 important things.
1. Using Unity Dependency Resolver
2. What is Lifetime manager and its significance.
Step 1: Create a regular MVC web application. create a new separate class library project. Add a two new interfaces and their concrete classes.
Step 2: Now, as per Dependency Injection principle (constructor injection), the dependee object will be passed as a parameter to the dependent class constructor. The same is implemented with Home controller.
private readonly IEmployee _employee; private readonly IEmployer _employer; public HomeController(IEmployee employee, IEmployer employer) { _employee = employee; _employer = employer; }But, you know that DefautControllerFactory expects a parameter-less constructor to instantiate the object for a controller. So, this implementation will cause a run-time exception.
Step 3: This is where Unity framework comes into picture. Using unity 2.0 , all the dependencies can be resolved thus addressing all the dependency issues.
Unity 2.0 dll can be downloaded from:
Unity2.0
Step 4: There are a few steps which we need to implement.
1. Add the Unity dlls to project.
a.Microsoft.Practices.Unity
b.Microsoft.Practices.Unity.Configuration
c.Microsoft.Practices.Unity.Interception
d.Microsoft.Practices.Unity.Interception.Configuration
2. Define UnityDependencyReolver class.
public class UnityDependencyResolver : IDependencyResolver { private IUnityContainer container; public UnityDependencyResolver(IUnityContainer container) { this.container = container; } public object GetService(Type serviceType) { if (!container.IsRegistered(serviceType)) { if (serviceType.IsAbstract || serviceType.IsInterface) { return null; } } return container.Resolve(serviceType); } public IEnumerable GetServices(Type serviceType) { return container.ResolveAll(serviceType); } }
3. Register the dependencies with Unity container.
var container = new UnityContainer();Usually above code will reside in global.ascx.cs file inside App_Start() method. But in real time, the no of dependencies will increase thus effecting readability of file. So, i used to isolate all the above code into a additional method "RegisterAll()" in Unity dependency resolver class.//Without using Lifetime Manager container.RegisterType<IEmployee, employee="">(); container.RegisterType<IEmployer, employer="">(); DependencyResolver.SetResolver(new UnityDependencyResolver(container));
Now, execute and see the result.
application getting executed and the code in Home controller's Index() method executed.
public ActionResult Index() { ViewBag.Message = "Execution Success"; return View(); }Step 5: Before looking into life time manager, lets do a small experiment. Let us modify the class files "Employee" and "Employer" as shown below.
public class Employee: IEmployee { private string _key; public int EmployeeId { get; set; } public string EmployeeName { get; set; } public string EmployeeAddress { get; set; } public Employee() { _key = Guid.NewGuid().ToString(); } public string Getkey() { return _key; } }
public class Employer: IEmployer { private string _key; public string EmployerName { get; set; } public string EmployerAddress { get; set; } public List<Employee> EmployeeList { get; set; } public Employer() { _key =Guid.NewGuid().ToString(); } public string Getkey() { return _key; } }From above definitions, we can see that the GetKey() method will return a unique key every time when a new instance is created for the class.
Step 6: A small change has to be done in Index() action method as well. Instead of a simple success message, i will send the key's of both the instances.
public ActionResult Index() { ViewBag.Message = "Time Stamp : "+DateTime.Now.ToString()+Environment.NewLine+ " Employee Key : "+_employee.Getkey()+Environment.NewLine+ " Employer Key : "+_employer.Getkey(); return View(); }Now see the result by pressing refresh button multiple times.
Refresh 1:
Refresh 2:
Now you can see that the key-id keep on changing. This means, every time when unity resolved the dependency, it will create a fresh instance of both Employee and Employer class.
Step 7: Just imagine if you are dealing with real time project which might have 1000 dependencies to resolve, and a 1000 new instances are getting created for every request. It will hit the performance.
This is where "LifetimeManager" will pitch in. Unity uses specific types that inherit from the LifetimeManager base class (collectively referred to as lifetime managers) to control how it stores references to object instances and how the container disposes of these instances.
Step 8: Before looking into types of LifetimeManagers, lets tweak our code a bit and see the results.
Change RegisterAll() method a bit and see the difference.
public static void RegisterAll() { var container = new UnityContainer();See the output by refreshing contentiously://Without using Lifetime Manager //container.RegisterType<IEmployee, Employee>(); //container.RegisterType<IEmployer, Employer>(); //DependencyResolver.SetResolver(new UnityDependencyResolver(container)); //using Lifetime Manager container.RegisterType<IEmployee, Employee> (new ContainerControlledLifetimeManager() ); container.RegisterType<IEmployer, Employer> (new ContainerControlledLifetimeManager() ); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); }
Refresh 1:
Refresh 2:
Now you can see that the key remained same even when time stamp changed.
This means Unity is maintaining the reference to existing instances, thus using them instead of re-creating them.
There are 6 types of Lifetime Managers available to work with.
With this we have seen how to resolve Dependencies using Unity frame work and significance of Lifetime Managers. Lets take a deep dive into different Lifetime Managers by implementing them practically.
Code Sample:
Unity with Lifetime Manager
Is it helpful for you? Kindly let me know your comments / Questions.
Hello there. Nice article! Just a small typo: in step "3. Register the dependencies with Unity container" there are two RegisterType() calls, instead of RegisterType().
ReplyDeletethanks Giumato. Updated the content... HTML Tags lost in transaltion . . . :)
DeleteGreat article. Just one small point; IDependencyResolver is part of MVC 3, your article seems to imply it is part of Unity 2
ReplyDeletethe code is not shared
ReplyDelete