標籤:
1
項目
先引入AutoFac 和AutoFac MVC兩個程式集到項目中
然後我們在MVC(UI層)的App_Start檔案夾下建立一個AutoFacConfig.cs類
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace FB.CMS.MvcSite.App_Start{ using Autofac; using Autofac.Integration.Mvc; using System.Reflection; using System.Web.Mvc; /// <summary> /// 這個類是我自己定義的一個類,主要用初始化AutoFac容器的相關資料 /// </summary> public class AutoFacConfig { public static void Register() { //初始化AutoFac的相關功能 /* 1.0 告訴AutoFac初始化資料倉儲層FB.CMS.Repository.dll中所有類的對象執行個體。這些對象執行個體以其介面的形式儲存在AutoFac容器中 2.0 告訴AutoFac初始化商務邏輯層FB.CMS.Services.dll中所有類的對象執行個體。這些對象執行個體以其介面的形式儲存在AutoFac容器中 3.0 將MVC預設的控制器工廠替換成AutoFac的工廠 */ //第一步: 構造一個AutoFac的builder容器 ContainerBuilder builder = new Autofac.ContainerBuilder(); //第二步:告訴AutoFac控制器工廠,控制器類的建立去哪些程式集中尋找(預設控制器工廠是去掃描bin目錄下的所有程式集) //2.1 從當前啟動並執行bin目錄下載入FB.CMS.MvcSite.dll程式集 Assembly controllerAss = Assembly.Load("FB.CMS.MvcSite"); //2.2 告訴AutoFac控制器工廠,控制器的建立從controllerAss中尋找(注意:RegisterControllers()方法是一個可變參數,如果你的控制器類的建立需要去多個程式集中尋找的話,那麼我們就再用Assembly controllerBss=Assembly.Load("需要的程式集名")載入需要的程式集,然後與controllerAss組成數組,然後將這個數組傳遞到RegisterControllers()方法中) builder.RegisterControllers(controllerAss); //第三步:告訴AutoFac容器,建立項目中的指定類的對象執行個體,以介面的形式儲存(其實就是建立資料倉儲層與商務邏輯層這兩個程式集中所有類的對象執行個體,然後以其介面的形式儲存到AutoFac容器記憶體中,當然如果有需要也可以建立其他程式集的所有類的對象執行個體,這個只需要我們指定就可以了) //3.1 載入資料倉儲層FB.CMS.Repository這個程式集。 Assembly repositoryAss = Assembly.Load("FB.CMS.Repository"); //3.2 反射掃描這個FB.CMS.Repository.dll程式集中所有的類,得到這個程式集中所有類的集合。 Type[] rtypes = repositoryAss.GetTypes(); //3.3 告訴AutoFac容器,建立rtypes這個集合中所有類的對象執行個體 builder.RegisterTypes(rtypes) .AsImplementedInterfaces(); //指明建立的rtypes這個集合中所有類的對象執行個體,以其介面的形式儲存 //3.4 載入商務邏輯層FB.CMS.Services這個程式集。 Assembly servicesAss = Assembly.Load("FB.CMS.Services"); //3.5 反射掃描這個FB.CMS.Services.dll程式集中所有的類,得到這個程式集中所有類的集合。 Type[] stypes = servicesAss.GetTypes(); //3.6 告訴AutoFac容器,建立stypes這個集合中所有類的對象執行個體 builder.RegisterTypes(stypes) .AsImplementedInterfaces(); //指明建立的stypes這個集合中所有類的對象執行個體,以其介面的形式儲存 //第四步:建立一個真正的AutoFac的工作容器 var container = builder.Build(); //我們已經建立了指定程式集的所有類的對象執行個體,並以其介面的形式儲存在AutoFac容器記憶體中了。那麼我們怎麼去拿它呢? //從AutoFac容器內部根據指定的介面擷取其實作類別的對象執行個體 //假設我要拿到IsysFunctionServices這個介面的實作類別的對象執行個體,怎麼拿呢? //var obj = container.Resolve<IsysFunctionServices>(); //只有有特殊需求的時候可以通過這樣的形式來拿。一般情況下沒有必要這樣來拿,因為AutoFac會自動工作(即:會自動去類的帶參數的建構函式中找與容器中key一致的參數類型,並將對象注入到類中,其實就是將對象賦值給建構函式的參數) //第五步:將當前容器中的控制器工廠替換掉MVC預設的控制器工廠。(即:不要MVC預設的控制器工廠了,用AutoFac容器中的控制器工廠替代)此處使用的是將AutoFac工作容器交給MVC底層 (需要using System.Web.Mvc;) DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //我們知道控制器的建立是調用MVC預設的控制器工廠,預設的控制器工廠是調用控制器類的無參建構函式 //可是我們如果要使用AutoFac自動工廠,將對象通過建構函式注入類中,那麼這個建構函式就需要帶參數 //如果我們將控制器的無參建構函式刪除,保留帶參數的建構函式,MVC預設的控制器工廠來建立控制的時候 //就會去調用無參的建構函式,可是這時候發現沒有無參的建構函式於是就報“沒有為該對象定義無參數的建構函式”錯誤 //既然報錯,那我們如果保留無參的建構函式,同時在聲明一個帶參數的建構函式是否可行呢? //答案;行是行,但是建立控制器的時候,MVC預設的控制器工廠調用的是無參建構函式,它並不會去調用有參的建構函式 //這時候,我們就只能將AutoFac它的控制器工廠替換調用MVC預設的控制器工廠(控制器由AutoFac的控制器工廠來建立) //而AutoFac控制器工廠在建立控制的時候只會掃描帶參數的建構函式,並將對象注入到帶參數的建構函式中 //AutofacDependencyResolver這個控制器工廠是繼承了 IDependencyResolver介面的,而IDependencyResolver介面是MVC的東西 //MVC預設的控制器工廠名字叫:DefaultControllerFactory //具體參考:http://www.cnblogs.com/artech/archive/2012/04/01/controller-activation-032.html } }}
然後我們在Global.asax檔案中的Application_Start()方法中來調用這個類
using FB.CMS.MvcSite.App_Start;using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Http;using System.Web.Mvc;using System.Web.Optimization;using System.Web.Routing;namespace FB.CMS.MvcSite{ // 注意: 有關啟用 IIS6 或 IIS7 傳統模式的說明, // 請訪問 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //第一: 在網站一啟動的時候就初始化AutoFac的相關功能 /* 1.0 告訴AutoFac初始化資料倉儲層FB.CMS.Repository.dll中所有類的對象執行個體。這些對象執行個體以其介面的形式儲存在AutoFac容器中 2.0 告訴AutoFac初始化商務邏輯層FB.CMS.Services.dll中所有類的對象執行個體。這些對象執行個體以其介面的形式儲存在AutoFac容器中 3.0 將MVC預設的控制器工廠替換成AutoFac的工廠 */ //具體做法就是我們去App_Start檔案夾下建立一個AutoFacConfig類,具體實現什麼功能去這個類中實現。然後再這裡調用下這個類 AutoFacConfig.Register(); } }}
使用Home控制器
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace FB.CMS.MvcSite.Controllers{ using FB.CMS.IServices; public class HomeController : Controller { IsysFunctionServices dal; public HomeController(IsysFunctionServices dal) //依賴建構函式進行對象注入 { this.dal = dal; //在建構函式中初始化HomeController控制器類的dal屬性 (這個dal屬性的類型是IsysFunctionServices) } public ActionResult Index() { var a = dal.QueryWhere(r => r.fID > 20).ToList(); //查詢 return View(); }}}
AutoFac (控制反轉IOC 與依賴注入DI)