1、常规写法,难道我们每次都new一个服务,如下面的UserService和CompanyService然后调用服务的Find方法去操作,为什么我们不让UserService和CompanyService服务注入进来呢?
public ActionResult Index()
{
DbContext context = new DbContext();
IUserService userService = new UserService(context);
User user = userService.Find(2);
return View(user);
}
public ActionResult Index2() { DbContext context = new DbContext(); ICompanyService companyService = new CompanyService(context);
Company company = companyService.Find(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;
///
/// 构造函数注入---控制器得是由容器来实例化
///
///
///
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(2); return View(user); }
public ActionResult Index2() { DbContext context = new DbContext(); ICompanyService companyService = this._iCompanyService;
Company company = companyService.Find(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配置
unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/> " "Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/> "MyContainer"> "Interception"/> "System.Data.Entity.DbContext, EntityFramework" mapTo="SchoolManager.EF.Model.SchoolDBEntities, SchoolManager.EF.Model"/> "SchoolManager.Bussiness.Interface.ICompanyService,SchoolManager.Bussiness.Interface" mapTo="SchoolManager.Bussiness.Service.CompanyService, SchoolManager.Bussiness.Service"/>