2、MVC+IOC容器+ORM结合

烈酒焚心 提交于 2019-11-29 01:55:48

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>

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!