Unity and injection with factories.
Last week in the office I just found a bug on how I was implementing a series of Inversion of Control chain using Microsoft Unity. To be precise, the bug has been found by one of the new guy in the team, Gary McLean Hall, the author of the book “APRESS – Pro WPF and Silverlight MVVM”.
Before starting with the explanation of the problem, let’s see what I am talking about. I believe that anyone of you know already concepts like “Inversion of Control” and ‘Dependency Injection”; if you don’t, just follow the links.
A classic injection mechanism.
A classic mechanism of IoC is the one used by the Unit of Work and Repository patterns, where a repository can’t exist without an injected unit of work able to control the transaction. So, in order to have such a kind of example, I have implemented a simple data layer that shows you these dependencies:
Now, for these two contracts we will need to concrete implementations like the following classes:
And the final touch will be the implementation. Now, I am not going to implement a full data layer in this post as it is not the target of this writing, instead I want to show you how to “inject” a unit of work …
- using System;
- using System.Linq;
- namespace InversionOfControl_dynamic
- {
- public sealed class Repository : IRepository
- {
- #region IRepository Members
-
public void Create
(T entity)</span> </li> - {
- this.unitOfWork.MarkNew(entity);
- }
- /// IRepository implementation removed to save space …
- #endregion
- #region Injection of the Unit of Work
- private IUnitOfWork unitOfWork;
- public Repository(IUnitOfWork unitOfWork)
- {
- this.unitOfWork = unitOfWork;
- }
- #endregion
- }
- }
</ol> </div></p> </div></p> </div> Now we can easily register the components with Unity and verify that when we call a **Repository** class, we are injecting a new **Unit of Work** using Unity. The following test is accomplishing this task:TDD the injection process- [TestFixture]
- public sealed class StandardFixture
- {
- private IUnityContainer container;
- [TestFixtureSetUp]
- public void InitializeTests()
- {
- container = new UnityContainer();
- container.RegisterType<IUnitOfWork, UnitOfWork>();
- container.RegisterType<IRepository, Repository>();
- }
- [Test]
- public void Assert_That_Unity_Can_Resolve_Dependency()
- {
- IRepository repository = container.Resolve<IRepository>();
- Assert.That(repository, Is.Not.Null);
- Assert.That(repository, Is.InstanceOf<Repository>());
- // Here I have created a public read-only property
- // for testing purposes
- Assert.That(repository, Has.Property(“UnitOfWork”).Not.Null);
- }
- }
Unit of Work Factory- public sealed class Factory
- {
- public static IUnitOfWork GetUnitOfWork()
- {
- return new UnitOfWork();
- }
- }
If I want to create a new instance of a repository I need to inform Unity, somehow, that it needs to call this method of the factory to create a new instance of an _IUnitOfWork_. But how? We found the class **InjectionFactory** ables to specify a delegate for the creation of a new object, like this code:
InjectionFactory declaration- container = new UnityContainer();
- container.RegisterType<IUnitOfWork>(new InjectionFactory(c =>
- Factory.GetUnitOfWork()));
- container.RegisterType<IRepository, Repository>();
Code Snippet- [Test]
- public void Assert_That_Unity_Can_Resolve_Dependency()
- {
- var currentRepository = container.Resolve<IRepository>();
- var currentUoW = currentRepository.GetType().GetProperty(“UnitOfWork”).GetValue(currentRepository, null);
- var expectedRepository = container.Resolve<IRepository>();
- var expectedUoW = currentRepository.GetType().GetProperty(“UnitOfWork”).GetValue(expectedRepository, null);
- Assert.That(currentUoW, Is.Not.Null);
- Assert.That(expectedUoW, Is.Not.Null);
- Assert.That(currentUoW, Is.Not.EqualTo(expectedUoW));
- }