Introduction
This article explains how we should extend Unity Container to register type mapping for classes not accessible to registration module.
Scenario
When it comes to implement dependency injection to existing solution, you might have a different layer which you need to inject dependencies for. In my project, I had a requirement to register data layer dependencies from Web project. As its data layer, I cannot reference Data Layer libraries to Web project. Below is the approach we are following to overcome this. Please suggest any other better approach to get this done.
The given approach uses UnityContainerExtention
created in middle layer and registers it in the first layer.
Using the Code
Once you have added Unity.mvc to your project, App_Start folder will get 2 files UnityConfig.cs and UnityWebActivator.cs added for Unity Container configuration and initiation. If you are new to dependency injection, please check this article for details.
Web Layer: Controller Action Method
using System.Web.Mvc;
using CodeSlice.Business.Interface;
public class HomeController : Controller
{
private readonly IDummy _businessDummy;
public HomeController(IDummy businessDummy)
{
_businessDummy = businessDummy;
}
public ActionResult About()
{
ViewBag.Message = _businessDummy.GetMessage();
return View();
}
}
Business Layer
namespace CodeSlice.Business.Interface
{
public interface IDummy
{
string GetMessage();
}
}
using CodeSlice.Business.Interface;
using CodeSlice.Data.Interface;
using CodeSlice.Data;
namespace CodeSlice.Business
{
public class Dummy : IDummy
{
private IDataDummy _data;
public Dummy(IDataDummy data)
{
_data = data;
}
public string GetMessage()
{
var result = data.GetMessage();
return result ;
}
}
}
Data Layer
namespace CodeSlice.Data.Interface
{
public interface IDummyData
{
string GetMessage();
}
}
using CodeSlice.Data.Interface;
namespace CodeSlice.Data
{
public string GetMessage()
{
return "From DB";
}
}
Extending Unity Container
Create custom dependency extension class extending UnityContainerExtension
in middle layer. Override Initialize
Method and Register Data Layer dependencies.
using CodeSlice.Data;
using CodeSlice.Data.Interface;
using Microsoft.Practices.Unity;
namespace CodeSlice.Business
{
public class DependencyInjectionExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IDataDummy, DataDummy>();
}
}
}
Add new extension to your unity container defined in RegisterType()
method of UnityConfig
class.
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDummy, Dummy>();
container.AddNewExtension<DependencyInjectionExtension>();
}
Please let me know your feedback or if you think if there is any other option to get this done without separating mapping out of the web project.