1、常规写法,难道我们每次都new一个服务,如下面的UserService和CompanyService然后调用服务的Find方法去操作,为什么我们不让UserService和CompanyService服务注入进来呢?
public ActionResult Index() { DbContext context = new DbContext(); IUserService userService = new UserService(context); User user = userService.Find<User>(2); return View(user); }
public ActionResult Index2() { DbContext context = new DbContext(); ICompanyService companyService = new CompanyService(context); Company company = companyService.Find<Company>(2);
return View(company); }
2、我们想要的实际效果是MVC请求进来的时候,实例化控制器的时候,就把UserService和CompanyService服务注入进来,但是下面的带参数的控制器构造函数TestController(IUserService userService, ICompanyService companyService)MVC是实例化不了的,MVC只能实例化不带参数的构造函数TestController()
public class TestController : Controller { private IUserService _iUserService = null; private ICompanyService _iCompanyService = null; /// <summary> /// 构造函数注入---控制器得是由容器来实例化 /// </summary> /// <param name="userService"></param> /// <param name="companyService"></param> public TestController(IUserService userService, ICompanyService companyService) { this._iUserService = userService; this._iCompanyService = companyService; } }
public ActionResult Index() { DbContext context = new DbContext(); IUserService userService = this._iUserService; User user = userService.Find<User>(2); return View(user); } public ActionResult Index2() { DbContext context = new DbContext(); ICompanyService companyService = this._iCompanyService; Company company = companyService.Find<Company>(2);
return View(company); }
3、在“1、看源码MVC如何实例化控制器”中提到MVC实例化控制器使用的是ControllerBuilder.GetControllerFactory()得到一个DefaultControllerFactory工厂,然后用工厂的CreateController方法利用反射去创建Controller实例,那么我们可以把工厂换成自己实现的自定义工厂不就可以了吗,ControllerBuilder还有个SetControllerFactory方法,自定义的控制器工厂CustomControllerFactory继承DefaultControllerFactory,微软的特点是virtual和abstract都是让我们来扩展的,那么我们复写GetControllerInstance方法,在GetControllerInstance方法里去构建容器
public class CustomControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { IUnityContainer container = DIFactory.GetContainer(); //return base.GetControllerInstance(requestContext, controllerType); return (IController)container.Resolve(controllerType); } }
4、在Application_Start中指定自定义的控制器工厂
public class MvcApplication : System.Web.HttpApplication {protected void Application_Start() { AreaRegistration.RegisterAllAreas();//注册区域 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//注册全局的Filter RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由 BundleConfig.RegisterBundles(BundleTable.Bundles);//合并压缩 ,打包工具 Combres ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());//设置自定义的控制器工厂 } }
5、依赖注入
public class DIFactory { public static IUnityContainer GetContainer() { IUnityContainer container = null; //container.RegisterType ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config"); Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); container = new UnityContainer(); section.Configure(container, "MyContainer"); return container; } }
6、进行Unity配置
<configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/> </configSections> <unity> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/> <containers> <container name="MyContainer"> <extension type="Interception"/> <register type="System.Data.Entity.DbContext, EntityFramework" mapTo="SchoolManager.EF.Model.SchoolDBEntities, SchoolManager.EF.Model"/> <register type="SchoolManager.Bussiness.Interface.ICompanyService,SchoolManager.Bussiness.Interface" mapTo="SchoolManager.Bussiness.Service.CompanyService, SchoolManager.Bussiness.Service"/> <register type="SchoolManager.Bussiness.Interface.IUserService,SchoolManager.Bussiness.Interface" mapTo="SchoolManager.Bussiness.Service.UserService, SchoolManager.Bussiness.Service"/> </container> </containers> </unity> </configuration>
原文地址:https://www.cnblogs.com/menglin2010/p/11428781.html