.NET Core - Autofac增強容器能力

本節學習利用第三方框架Autofac來增強容器能力,並引入面向切面(AOP)編程的概念。

 

那麼,先來了解一下

什麼時候需要引入第三方容器組件呢?

  • 基於名稱的注入

  • 屬性注入

  • 子容器

  • 基於動態代理的AOP

 

核心擴展點

public interface IServiceProviderFactory<TContainerBuilder>

第三方的擴展框架都是基於這個接口做擴展的

 

Autofac擴展包

  • Autofac.Extensions.DependencyInjection

  • Autofac.Extras.DynamicProxy

 

下面,我們就通過代碼來演示如何使用Autofac以及使用Autofac來實現上述幾種情況。

 

代碼演示

首先說一下,代碼架構,這裏主要是定義了一個接口,然後定義了2個實現該接口的類,其中第二個類包含一個屬性,用於驗證屬性注入。類的代碼如下


public interface IMyService 
{
    void show();
}

public class MyService : IMyService
{
    public void show()
    {
        Console.WriteLine($"this is MyService.show,{GetHashCode()}");
    }
}

public class MyServiceV2 : IMyService
{
    public MyNameService myNameService { get; set; }
    public void show()
    {
        Console.WriteLine($"this is MyServiceV2.show,{GetHashCode()},MyNameService是否爲空:{myNameService==null}");
    }
}

public class MyNameService { }


 

Autofac使用步驟


1.註冊第三方組件入口

在使用第三方組件時,我們需要先通過配置來啓用第三方組件,如下,我們在CreateHostBuilder中添加如下語句。

.UseServiceProviderFactory(new AutofacServiceProviderFactory())

2.服務註冊入口

組件入口註冊後,我們需要定義第三方組件自己的服務註冊入口,我們可以在startup裏新增一個ConfigureContainer方法來實現,方法入參是Autofac.ContainerBuilder,其實,這裏我們的服務註冊進默認的容器後,會被Autofac接替,然後執行ConfigureContainer.

public void ConfigureContainer(ContainerBuilder containerBuilder)
{
    //...
}

3.接收Autofac的容器

之後,我們需要創建一個作用域,用於在根容器內接收Autofac的容器對象。

public ILifetimeScope AutofacContainer { get; private set; }
//根容器獲取
this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();

到這裏,我們就完成了所有的準備步驟,可以開始上述幾種場景的演示了。

 

常規注入

在這之前,我們先了解一下常規注入方式以及獲取方式,這裏注意一下,Autofac的注入方式是先注入服務在指定其類型。如下

//常規註冊
containerBuilder.RegisterType<MyService>();//未指定類型,通過IMyService不能獲取
containerBuilder.RegisterType<MyService>().As<IMyService>();
containerBuilder.RegisterType<MyServiceV2>().As<IMyService>();

獲取方式如下

var service = this.AutofacContainer.Resolve<IMyService>();

Autofac的服務獲取方式是一組以Resolve...開頭的方法,比如,下面要說的命名服務的獲取方式可通過ResolveNamed方法獲取。

 

基於名稱的注入及獲取

//註冊
containerBuilder.RegisterType<MyService>().Named<IMyService>("myService");
//獲取
IMyService myService = this.AutofacContainer.ResolveNamed<IMyService>("myService");

屬性注入

屬性注通過PropertiesAutowired來開啓屬性注入,在屬性注入前要先註冊要注入的服務

//注入要注入的服務
containerBuilder.RegisterType<MyNameService>();
//開啓屬性注入
containerBuilder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired();

AOP編程

Autofac提供了一個IInterceptor的接口,用於提供AOP的能力,我們可以通過實現該接口,將一些特定的邏輯嵌入到方法的切面中,並控制是否執行原有代碼邏輯,一般,我們稱該類爲攔截器,如下,是一個攔截器示例

public class Interceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"{invocation.Method.Name}執行前");
        //不調用該方法,可禁用原有邏輯
        invocation.Proceed();
        Console.WriteLine($"{invocation.Method.Name}執行後");
    }
}

那麼,如何開啓攔截器呢?主要有以下幾步

  1. 注入攔截器

  2. 通過InterceptedBy來定義允許的類型

  3. 開啓攔截器開關,分爲類攔截器和接口攔截器(常用)

代碼如下:

//注入攔截器
containerBuilder.RegisterType<Interceptor>();
//定義允許的類型並開啓攔截器
containerBuilder.RegisterType<MyService>().As<IMyService>().InterceptedBy(typeof(Interceptor)).EnableInterfaceInterceptors();

子容器

我們知道,通過Scope可以創建子容器,在Autofac中,可以通過InstancePerMatchingLifetimeScope來創建特定名稱的子容器,一般使用在期望某一服務不在根容器創建,但又希望它在一定的範圍內是單例的情況下。

containerBuilder.RegisterType<MyServiceV2>().InstancePerMatchingLifetimeScope("myscope");

也可以通過如下代碼來驗證容器是否是單例

using (var myscope = AutofacContainer.BeginLifetimeScope("myscope"))
{
    var service0 = myscope.Resolve<MyServiceV2>();
    using (var scope = myscope.BeginLifetimeScope())
    {
        var service1 = myscope.Resolve<MyServiceV2>();
        var service2 = myscope.Resolve<MyServiceV2>();
        Console.WriteLine($"service1==service2?{service1 == service2}");
        Console.WriteLine($"service1==service2?{service0 == service1}");
    }
}

本節到此就要結束了,從下節將開始配置框架的學習。

 

源碼可訪問

https://github.com/IronMarmot/Samples/tree/master/CoreSamples

更多課程詳細內容,可識別下方二維碼購買。

掃描二維碼購買課程,可後臺留言獲得10元紅包返現。

部分內容來源於網絡,侵刪。

更多精彩內容,請微信搜索攻城獅客棧 或掃描下方二維碼

------------------------------------------------------------------------------

公衆號:攻城獅客棧

CSDN:畫雞蛋的不止達芬奇

 

                                                                 

讓我們一起變的更優秀。


 

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