2、MVC+IOC容器+ORM結合

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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章