當(dāng)前位置:首頁 > IT技術(shù) > Web編程 > 正文

.net core2.1 三層中使用Autofac代替原來Ioc
2021-10-22 10:09:28

? 首先,現(xiàn)有的三層項(xiàng)目的結(jié)構(gòu)

.net core2.1  三層中使用Autofac代替原來Ioc_Autofac

其中? 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;
//通過構(gòu)造函數(shù)注入 repository
public PersonService(IPersonRepository personRespository)
{
_personRespository = personRespository;
}
public string Eat()
{
return _personRespository.Eat();
}
}


?

一、安裝Autofac

? ? ? nuget上安裝Autofac

.net core2.1  三層中使用Autofac代替原來Ioc_程序集_02

?

二、替換內(nèi)置的DI框架

    將Startup.cs中的??ConfigureServices??返回類型改為??IServiceProvider,然后新起一個方法RegisterAutofac把創(chuàng)建容器的代碼放到其中,然后建一個??AutofacModuleRegister類繼承Autofac的Module,然后重寫Module的Load方法 來存放新組件的注入代碼,避免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)
{
//實(shí)例化Autofac容器
var builder = new ContainerBuilder();
//將Services中的服務(wù)填充到Autofac中
builder.Populate(services);
//新模塊組件注冊
builder.RegisterModule<AutofacModuleRegister>();
//創(chuàng)建容器
var Container = builder.Build();
//第三方IOC接管 core內(nèi)置DI容器
return new AutofacServiceProvider(Container);
}



public class AutofacModuleRegister:Autofac.Module
{
//重寫Autofac管道Load方法,在這里注冊注入
protected override void Load(ContainerBuilder builder)
{
//注冊Service中的對象,Service中的類要以Service結(jié)尾,否則注冊失敗
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注冊Repository中的對象,Repository中的類要以Repository結(jié)尾,否則注冊失敗
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
}
/// <summary>
/// 根據(jù)程序集名稱獲取程序集
/// </summary>
/// <param name="AssemblyName">程序集名稱</param>
/// <returns></returns>
public static Assembly GetAssemblyByName(String AssemblyName)
{
return Assembly.Load(AssemblyName);
}
}


?

此時Autofac基本使用已經(jīng)配好了。

三、測試效果

? ? ? ? 修改HomeController?實(shí)現(xiàn)注入Service



public class HomeController : Controller
{
private IPersonService _personService;

//通過構(gòu)造函數(shù)注入Service
public HomeController(IPersonService personService)
{
_personService = personService;
}
public IActionResult Index()
{
ViewBag.eat = _personService.Eat();
return View();
}
}


頁面結(jié)果:

.net core2.1  三層中使用Autofac代替原來Ioc_.net core_03

四、一個接口多個實(shí)現(xiàn)的情況

   比喻我現(xiàn)在在Service?中建三個類,IPayService, WxPayService,AliPayService,其中WxPayService,AliPayService都實(shí)現(xiàn)接口IPayService。



public interface IPayService
{
string Pay();
}



public class AliPayService : IPayService
{
public string Pay()
{
return "支付寶支付";
}
}



public class WxPayService : IPayService
{
public string Pay()
{
return "微信支付";
}
}


? 先試一下結(jié)果,修改HomeController



public class HomeController : Controller
{
private IPersonService _personService;
private IPayService _payService;

//通過構(gòu)造函數(shù)注入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


輸出頁面:

.net core2.1  三層中使用Autofac代替原來Ioc_.net core_04

? ? 最后得到的是微信支付,因?yàn)閮蓚€對象實(shí)現(xiàn)一個接口的時候,注冊時后面注冊的會覆蓋前面注冊的。如果我想得到支付寶支付要怎么做呢?

 我們可以用另外一種注冊方式RegisterType,修改注冊方式AutofacModuleRegister.cs。

?



public class AutofacModuleRegister:Autofac.Module
{
//重寫Autofac管道Load方法,在這里注冊注入
protected override void Load(ContainerBuilder builder)
{
//注冊Service中的對象,Service中的類要以Service結(jié)尾,否則注冊失敗
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注冊Repository中的對象,Repository中的類要以Repository結(jié)尾,否則注冊失敗
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
//單獨(dú)注冊
builder.RegisterType<WxPayService>().Named<IPayService>(typeof(WxPayService).Name);
builder.RegisterType<AliPayService>().Named<IPayService>(typeof(AliPayService).Name);
}
/// <summary>
/// 根據(jù)程序集名稱獲取程序集
/// </summary>
/// <param name="AssemblyName">程序集名稱</param>
/// <returns></returns>
public static Assembly GetAssemblyByName(String AssemblyName)
{
return Assembly.Load(AssemblyName);
}
}


?

用Named區(qū)分兩個組件的不同,后面的typeof(WxPayService).Name?是任意字符串,這里直接用這個類名作標(biāo)識,方便取出來時也是用這個名字,不易忘記。

然后就是取出對應(yīng)的組件了,取的時候用Autofac的 上下文(IComponentContext)?,修改HomeController



public class HomeController : Controller
{
private IPersonService _personService;
private IPayService _wxPayService;
private IPayService _aliPayService;
private IComponentContext _componentContext;//Autofac上下文
//通過構(gòu)造函數(shù)注入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


結(jié)果:

.net core2.1  三層中使用Autofac代替原來Ioc_Ioc_05

?

完成。

?

    

?

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >