zoukankan      html  css  js  c++  java
  • .NET Core下自带容器IServiceCollection以及AutoFac以及AutoFac中AOP简介

    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://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");
            }
        }
    }
    View Code

    需要通过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

     2、ConfigureService需要一个返回值,IServiceProvider(在.NET Core3.0中不需要替换)

     

     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

     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也要稍作修改:

     添加两个测试类:

     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;
         }
    
    }
  • 相关阅读:
    Debian 9/Ubuntu 18添加rc.local开机自启的方法
    第一次使用Debian9所遇到的问题
    Open-Falcon注册时点击Sign up按钮没反应
    使用VMware虚拟机里的Ubuntu18.04部署RAID 10磁盘阵列
    Ubuntu18.04下Ansible的基本使用
    Go语言求水仙花数(for循环)
    自研模块加载器(四) 模块资源定位-异步加载
    自研模块加载器(三) module模块构造器设计-模块数据初始化
    自研模块加载器(二) 加载器结构与设计导论
    自研模块加载器(一) 模块系统概述与自定义模块规范书写规定
  • 原文地址:https://www.cnblogs.com/taotaozhuanyong/p/11562184.html
Copyright © 2011-2022 走看看