什麼情況下需要引入第三方容器組件?
實際上是大部分情況默認的容器組件是夠我們使用的,當我們需要一些特殊的場景比如:
- 基於名稱的注入:我們需要按照名稱來區分它不同的實現的時候
- 屬性注入:直接把服務註冊到某一個類的屬性裏面去,而不需要定義構造函數
- 子容器
- 基於動態代理的AOP:當我們需要在服務中注入我們額外的行爲的時候
.Net Core 的依賴注入框架的核心擴展點
public interface IServiceProviderFactory<TContainerBuilder>
第三方的依賴注入容器都是使用了這個類作爲擴展點,把自己注入到我們整個的框架裏面來。
爲什麼選擇Autofac?
Autofac是.NET社區下面最老牌的容器框架之一,本人在項目中用得最多的也是Autofac。常用的Ioc和Aop器還有Unity、Spring.Net。
Autofac的核心組件包
- Microsoft.Extensions.Configuration. Abstractions
- Microsoft.Extensions.Configuration
我們可以通過NuGet進行安裝。
配置Autofac容器
我們需要在我們的Program入口加一行代碼,就是UseServiceProviderFactory(new AutofacServiceProviderFactory())
另外我們還需要在Startup添加一個方法ConfigureContainer,他的入參是Autofac的ContainerBuilder
Autofac的註冊方式
它的註冊方式與.Net Core默認容器的註冊方式是略有不同的
我們先註冊具體的實現,然後再告我們想把它標記爲哪個服務的類型
builder.RegisterType<MyService>().As<IMyService>();
命名註冊
當我們需要比一個服務註冊多次,並且用不同的命名來作爲區分的時候我們就可以使用這種方式
builder.RegisterType<MyServiceV2>().Named<IMyService>("service2");
屬性註冊
屬性註冊只需要在末尾加上.PropertiesAutowired()即可
builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired();
AOP場景
AOP主要應用場景是指我們在不期望改變原有類的情況下,在方法執行時嵌入一些邏輯,讓我們可以在方法執行的切面上任意的插入我們的邏輯。
AOP切面的創建
我們新建一個MyInterceptor的類並繼承IInterceptor接口。IInterceptor是Autofac的面向切面的最重要的一個接口,它可以讓把我們的邏輯注入到方法的切面裏面去。
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"Intercept before,Method:{invocation.Method.Name}");//方法執行前
invocation.Proceed();//執行我們的方法
Console.WriteLine($"Intercept after,Method:{invocation.Method.Name}");//方法執行後
}
}
invocation.Proceed();是指我們具體方法的執行,如果這一句不執行的話就相當於把我們的切面方法攔截掉。打個比方我們需要做登錄驗證,則可以把invocation.Proceed()放到if語句裏面,如果驗證通過則執行,如果不通過則不執行。
那麼顯而易見invocation.Proceed()後的代碼就是在具體方法執行後執行。
啓用AOP切面
把攔截器註冊到容器裏面去
builder.RegisterType<MyInterceptor>();
註冊需要添加AOP切面的服務
builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors();
InterceptedBy(typeof(MyInterceptor))指開啓攔截器,並指定攔截方法爲MyInterceptor。
EnableInterfaceInterceptors()開啓允許接口攔截器
攔截器又分兩種:接口攔截器、類攔截器,我們常用的是接口攔截器,當我們的服務的類型是接口的時候我們就需要使用這種方式。如果我們沒有基於接口設計我們的類,而是直接實現類的話我能就需要類攔截器。類攔截器就需要我們把方法設計爲虛方法,這樣子允許繼承類重載的情況下才可以攔截我們的具體方法。