在现代Web应用程序开发中,解耦是一个重要的目标。解耦可以帮助构建更加灵活、可维护和可测试的代码。依赖注入(DI)是一种实现解耦的常用技术。Unity是一个流行的依赖注入容器,可以与ASP.NET MVC框架无缝集成。本文将介绍如何在ASP.NET MVC框架中使用Unity IoC容器。
构建容器
首先,需要构建容器。在Global.asax文件中,可以将Unity容器作为HTTP应用程序的属性来存储。这样,容器的状态可以在应用程序的整个执行过程中保持不变。定义了一个接口IContainerAccessor,用于访问容器:
public interface IContainerAccessor
{
IUnityContainer Container { get; }
}
接下来,在Global类中实现这个接口:
public class MvcApplication : HttpApplication, IContainerAccessor
{
private static IUnityContainer _container;
public static IUnityContainer Container
{
get { return _container; }
}
IUnityContainer IContainerAccessor.Container
{
get { return Container; }
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
InitContainer();
ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory));
}
protected void Application_End(object sender, EventArgs e)
{
CleanUp();
}
private static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
private static void InitContainer()
{
if (_container == null)
{
_container = new UnityContainer();
_container.RegisterType();
}
}
private static void CleanUp()
{
if (Container != null)
{
Container.Dispose();
}
}
}
在Application_Start事件中,注册了所有相关的依赖项,并在Application_End事件中释放了容器。
Unity控制器工厂
接下来,需要实现一个控制器工厂。控制器工厂的职责是为传入的HTTP请求实例化相关的控制器。需要实现IControllerFactory接口:
public class UnityControllerFactory : IControllerFactory
{
public IController CreateController(RequestContext requestContext, string controllerName)
{
IContainerAccessor containerAccessor = requestContext.HttpContext.ApplicationInstance as IContainerAccessor;
Assembly currentAssembly = Assembly.GetExecutingAssembly();
var controllerTypes = from t in currentAssembly.GetTypes()
where t.Name.Contains(controllerName + "Controller")
select t;
if (controllerTypes.Count() > 0)
{
return containerAccessor.Container.Resolve(controllerTypes.First()) as IController;
}
return null;
}
public void ReleaseController(IController controller)
{
controller = null;
}
}
CreateController方法使用请求上下文参数来检索当前应用程序实例,并从中获取Unity容器。然后,容器将注入控制器所需的依赖项。
要注入的类
编写了一个简单的MessageService类,它返回一条消息,并继承自IMessageService接口,该接口声明了GetMessage方法:
public interface IMessageService
{
string GetMessage();
}
public class MessageService : IMessageService
{
public string GetMessage()
{
return "Hello Controller!";
}
}
控制器
最后,实现了HomeController类:
[HandleError]
public class HomeController : Controller
{
[Dependency]
public IMessageService MessageService { get; set; }
public ActionResult Index()
{
ViewData["Message"] = MessageService.GetMessage();
return View();
}
public ActionResult About()
{
return View();
}
}