.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:画鸡蛋的不止达芬奇

 

                                                                 

让我们一起变的更优秀。


 

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