.net core2.1 三層中使用Autofac代替原來Ioc
阿新 • • 發佈:2018-06-17
mpat quest cookie sse asi viewdata inter .net core control
首先,現有的三層項目的結構
其中 Repository
public interface IPersonRepository { string Eat(); }
public class PersonRepository : IPersonRepository { public string Eat() { return "吃飯"; } }
Service
public interface IPersonService {string Eat(); }
public class PersonService : IPersonService { private IPersonRepository _personRespository; //通過構造函數註入 repository public PersonService(IPersonRepository personRespository) { _personRespository = personRespository; }public string Eat() { return _personRespository.Eat(); } }
一、安裝Autofac
nuget上安裝Autofac
二、替換內置的DI框架
將Startup.cs中的ConfigureServices
返回類型改為IServiceProvider,然後新起一個方法RegisterAutofac把創建容器的代碼放到其中,然後建一個
AutofacConfig 類來存放具體的註入代碼,避免
Startup.cs文件代碼過多混亂。
public IServiceProvider ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); return RegisterAutofac(services);//註冊Autofac } private IServiceProvider RegisterAutofac(IServiceCollection services) { //實例化Autofac容器 var builder = new ContainerBuilder(); builder.Populate(services); //Autofac註冊對象 AutofacConfig.RegisterObj(builder); var Container = builder.Build(); //第三方IOC接管 core內置DI容器 return new AutofacServiceProvider(Container); }
public class AutofacConfig { public static void RegisterObj(ContainerBuilder builder) { //註冊Service中的組件,Service中的類要以Service結尾,否則註冊失敗 builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces(); //註冊Repository中的組件,Repository中的類要以Repository結尾,否則註冊失敗 builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces(); } /// <summary> /// 根據程序集名稱獲取程序集 /// </summary> /// <param name="AssemblyName">程序集名稱</param> /// <returns></returns> public static Assembly GetAssemblyByName(String AssemblyName) { return Assembly.Load(AssemblyName); } }
此時Autofac基本使用已經配好了。
三、測試效果
修改HomeController 實現註入Service
public class HomeController : Controller { private IPersonService _personService; //通過構造函數註入Service public HomeController(IPersonService personService) { _personService = personService; } public IActionResult Index() { ViewBag.eat = _personService.Eat(); return View(); } }
頁面結果:
四、一個接口多個實現的情況
比喻我現在在Service 中建三個類,IPayService, WxPayService,AliPayService,其中WxPayService,AliPayService都實現接口IPayService。
public interface IPayService { string Pay(); }
public class AliPayService : IPayService { public string Pay() { return "支付寶支付"; } }
public class WxPayService : IPayService { public string Pay() { return "微信支付"; } }
先試一下結果,修改HomeController
public class HomeController : Controller { private IPersonService _personService; private IPayService _payService; //通過構造函數註入Service public HomeController(IPersonService personService,IPayService payService) { _personService = personService; _payService = payService; } public IActionResult Index() { ViewBag.eat = _personService.Eat(); ViewBag.pay = _payService.Pay(); return View(); } }
View
@{ ViewData["Title"] = "Home Page"; } @ViewBag.eat <br /> @ViewBag.pay
輸出頁面:
最後得到的是微信支付,因為兩個對象實現一個接口的時候,註冊時後面註冊的會覆蓋前面註冊的。如果我想得到支付寶支付要怎麽做呢?
我們可以用另外一種註冊方式RegisterType,修改註冊方式AutofacConfig.cs。
public static void RegisterObj(ContainerBuilder builder) { //註冊Service中的組件,Service中的類要以Service結尾,否則註冊失敗 builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces(); //註冊Repository中的組件,Repository中的類要以Repository結尾,否則註冊失敗 builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces(); //單獨註冊 builder.RegisterType<WxPayService>().Named<IPayService>(typeof(WxPayService).Name); builder.RegisterType<AliPayService>().Named<IPayService>(typeof(AliPayService).Name); } /// <summary> /// 根據程序集名稱獲取程序集 /// </summary> /// <param name="AssemblyName">程序集名稱</param> /// <returns></returns> public static Assembly GetAssemblyByName(String AssemblyName) { return Assembly.Load(AssemblyName); }
用Named區分兩個組件的不同,後面的typeof(WxPayService).Name 是任意字符串,這裏直接用這個類名作標識,方便取出來時也是用這個名字,不易忘記。
然後就是取出對應的組件了,取的時候用Autofac的 上下文(IComponentContext) ,修改HomeController
public class HomeController : Controller { private IPersonService _personService; private IPayService _wxPayService; private IPayService _aliPayService; private IComponentContext _componentContext;//Autofac上下文 //通過構造函數註入Service public HomeController(IPersonService personService, IComponentContext componentContext) { _personService = personService; _componentContext = componentContext; //解釋組件 _wxPayService = componentContext.ResolveNamed<IPayService>(typeof(WxPayService).Name); _aliPayService =componentContext.ResolveNamed<IPayService>(typeof(AliPayService).Name); } public IActionResult Index() { ViewBag.eat = _personService.Eat(); ViewBag.wxPay = _wxPayService.Pay(); ViewBag.aliPay = _aliPayService.Pay(); return View(); } }
Index View:
@{ ViewData["Title"] = "Home Page"; } @ViewBag.eat <br /> @ViewBag.wxPay <br /> @ViewBag.aliPay
結果:
完成。
.net core2.1 三層中使用Autofac代替原來Ioc