在现代软件开发中,依赖注入(Dependency Injection,DI)是一种常用的设计模式,它可以帮助降低代码的耦合度,提高代码的可测试性和可维护性。Munq是一个轻量级的IOC容器,它支持ASP.NET MVC项目,并且可以通过NuGet包轻松集成。本文将演示如何在ASP.NET MVC项目中集成Munq IOC容器,并使用依赖注入重构AccountController。
在之前的一些文章中,已经介绍了Munq IOC容器的基本概念和使用方法。随着ASP.NET MVC3的发布,对Munq进行了更新,增加了对ASP.NET MVC3的支持,包括实现了IDependencyResolver接口和Common Service Locator。这些更新使得Munq更加适合在ASP.NET MVC3项目中使用。
首先,需要创建一个ASP.NET MVC3项目。在Visual Studio中,选择“文件”->“新建”->“项目”,然后选择“ASP.NET MVC 3 Web应用程序”。在创建项目时,选择“Internet应用程序”选项,并选择ASP.NET作为视图引擎,同时勾选“包含单元测试”选项。这样,就创建了一个包含首页、关于页面和基于SQL Express表单认证的简单项目。
在AccountController.cs文件中,可以看到控制器的依赖项是在Initialize方法中设置的。为了使用依赖注入,需要移除这个方法,并添加一个构造函数,该构造函数包含认证和会员服务作为参数。同时,FormsService和MembershipService属性暴露了不应该由控制器用户需要的实现细节。暂时不修复这个问题,因为这会破坏许多单元测试,并且对于展示如何使依赖注入工作并不重要。
public IFormsAuthenticationService FormsService { get; set; }
public IMembershipService MembershipService { get; set; }
public AccountController(IFormsAuthenticationService formsService, IMembershipService membershipService)
{
FormsService = formsService;
MembershipService = membershipService;
}
构建解决方案后,发现单元测试中出现了错误,提示AccountController没有无参数的构造函数。需要修改AccountControllerTest.cs中的GetAccountController方法:
private static AccountController GetAccountController()
{
RequestContext requestContext = new RequestContext(new MockHttpContext(), new RouteData());
AccountController controller = new AccountController(new MockFormsAuthenticationService(), new MockMembershipService())
{
Url = new UrlHelper(requestContext),
};
controller.ControllerContext = new ControllerContext()
{
Controller = controller,
RequestContext = requestContext
};
return controller;
}
using System.Web.Mvc;
using Munq.MVC3;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(MunqMvc3Sample.App_Start.MunqMvc3Startup),
"PreStart")]
namespace MunqMvc3Sample.App_Start {
public static class MunqMvc3Startup {
public static void PreStart() {
DependencyResolver.SetResolver(new MunqDependencyResolver());
var ioc = MunqDependencyResolver.Container;
// TODO: Register Dependencies
ioc.Register();
ioc.Register();
ioc.Register();
ioc.Register(c => Membership.Provider);
}
}
}