欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

程序员文章站 2022-07-02 13:19:50
https://www.cnblogs.com/artech/p/net-core-di-01.html 大内老A的在.NET Core下对这些的介绍,有一系列文章 https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html https://w ......

 大内老a的在.net core下对这些的介绍,有一系列文章

https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html

https://www.cnblogs.com/artech/p/dependency-injection-in-asp-net-core.html

https://www.zybuluo.com/dasajia2lang/note/1481011

下面开始

在上一篇的笔记中,在.net freamwork中,有一个第三方容器unity,可以实现注入,但是在.net core里面,有一个iservicecollection,这个是.net core框架自带的一个容器,和unity很相似,都是个容器。

下面我们新建一个控制台程序,在控制台程序中,对iservicecollection的使用做介绍。

下面代码,是本次实例中需要注入的类型,需要用的倒是再点开来看吧

namespace bingle.core.interface
{
    public interface itestservicea
    {
        void show();
    }
}
namespace bingle.core.service
{
    public class testservicea : itestservicea
    {
        public void show()
        {
            console.writeline("a123456");
        }
    }
}

namespace bingle.core.interface
{
    public interface itestserviceb
    {
        void show();
    }
}

namespace bingle.core.service
{
    public class testserviceb : itestserviceb
    {
        
        public testserviceb(itestservicea itestservice)
        {
          
        }


        public void show()
        { 
            console.writeline($"this is testserviceb b123456");
        }
    }
}


namespace bingle.core.interface
{
    public interface itestservicec
    {
        void show();
    }
}

namespace bingle.core.service
{
    public class testservicec : itestservicec
    {
        public testservicec(itestserviceb itestserviceb)
        {
        }
        public void show()
        {
            console.writeline("c123456");
        }
    }
}

namespace bingle.core.interface
{
    public interface itestserviced
    {
        void show();
    }
}

namespace bingle.core.service
{
    public class testserviced : itestserviced
    {
        public void show()
        {
            console.writeline("d123456");
        }
    }
}

需要通过nuget包,把iservicecollection依赖的dll文件进入进来

microsoft.extensions.dependencyinjection

使用容器的三部曲:实例化一个容器、注册、获取服务

 iservicecollection container = new servicecollection();
 // iservicecollection
 container.addtransient<itestservicea, testservicea>();  // 瞬时生命周期  每一次获取的对象都是新的对象
 container.addsingleton<itestserviceb, testserviceb>(); // 单例生命周期  在容器中永远只有当前这一个
 container.addscoped<itestservicec, testservicec>();    //当前请求作用域内  只有当前这个实例

 container.addsingleton<itestserviced>(new testserviced());  // 也是单例生命周期

 serviceprovider provider = container.buildserviceprovider();

 itestservicea testa = provider.getservice<itestservicea>();
 itestservicea testa1 = provider.getservice<itestservicea>();
 console.writeline(object.referenceequals(testa, testa1));

 itestserviceb testb = provider.getservice<itestserviceb>();
 itestserviceb testb1 = provider.getservice<itestserviceb>();
 console.writeline(object.referenceequals(testb, testb1));
  
 itestservicec testc = provider.getservice<itestservicec>();
 itestservicec testc1 = provider.getservice<itestservicec>();
 console.writeline(object.referenceequals(testc, testc1));
  
 iservicescope scope = provider.createscope();
 itestservicec testc3 = provider.getservice<itestservicec>();
 var testc4 = scope.serviceprovider.getservice<itestservicec>();
 console.writeline(object.referenceequals(testc3, testc4));
  
 itestserviced testd = provider.getservice<itestserviced>();
 itestserviced testd1 = provider.getservice<itestserviced>();
 console.writeline(object.referenceequals(testd, testd1));

 

autofac也是个容器,下面在core中把autofac整合进来。

1、在nuget中添加autofac

.NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

 

 2、configureservice需要一个返回值,iserviceprovider(在.net core3.0中不需要替换)

 .NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

 

 3、实例化一个容器:

containerbuilder containerbuilder = new containerbuilder();

4、注册服务,自定义一个类型,继承module,并重写load方法:

public class customautofacmodule:module
{ 
    /// <summary>
    ///  当前这module 专用做服务注册
    /// </summary>
    /// <param name="builder"></param>
    protected override void load(containerbuilder builder)
    {
        builder.registertype<testservicea>().as<itestservicea>().singleinstance();
        builder.registertype<testserviceb>().as<itestserviceb>().singleinstance();
        builder.registertype<testservicec>().as<itestservicec>().singleinstance();
        builder.registertype<testserviced>().as<itestserviced>().singleinstance();
    }
}

在startup.cs中的configureservices()方法中加上一下代码:

// services 默认的注册服务,还需要处理控制器实例相关的的工作。 
containerbuilder.populate(services); // autofac 全权接管了之前这个service的所有工作

containerbuilder.registermodule<customautofacmodule>();
icontainer container = containerbuilder.build();
return new autofacserviceprovider(container);

autofac支持aop

 aop存在的意义,是在这个方法执行之前做什么事,做完这个方法之后,又做什么事。

1、安装nuget包,dynamicproxy

.NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

 

 2、自定义一个类,继承iinterceptor接口

 public class customautofacaop : iinterceptor
 {
     public void intercept(iinvocation invocation)
     {
         console.writeline($"method is {invocation.method.name}");
         console.writeline($"arguments is {string.join(';', invocation.arguments)}");

         invocation.proceed();// 这里表示继续执行,就去执行之前应该执行的动作了

         console.writeline("**************");

     }
 }

在之前的customautofacmodule也要稍作修改:

.NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

 

 

 添加两个测试类:

 

 public interface ia
 {
     void show();
 }

 [intercept(typeof(customautofacaop))]
 public class a : ia
 {
     public void show()
     {
         console.writeline("cm");
     }
 }

 

 

 

 在一个控制器下,通过构造函数的方式来实现注入:

 public class binglecontroller : controller
 {
     private iloggerfactory _factory = null;
     private ilogger<secondcontroller> _ilogger = null;

     private itestservicea _testservicea = null;
     private itestserviceb _testserviceb = null;
     private itestservicec _testservicec = null;
     private itestserviced _testserviced = null;
     private ia _a = null;

     public binglecontroller(iloggerfactory factory, ilogger<secondcontroller> ilogger,
       itestservicea testservicea,
       itestserviceb testserviceb,
       itestservicec testservicec,
       itestserviced testserviced,
       ia a)
     {
         _factory = factory;
         _ilogger = ilogger;
         _testservicea = testservicea;
         _testserviceb = testserviceb;
         _testservicec = testservicec;
         _testserviced = testserviced;
         _a = a;
     }

}