zoukankan      html  css  js  c++  java
  • .Net Core AutoFac 使用方法讲解大全,具体详细使用知识总结

    • AutoFac 具体使用知识总结

    • 阅读前提示 AutoFac 只是众多IOC框架的其中一种, 比较主流的有Unityautofacspring.netMEFInjectionAsp.Net CoreServiceCollection,等一些,还有一些,可能自己实现这一套东西。

    1.为什么使用AutoFac? (自己的理解综合所链接的因素)

    1. 传说是速度最快的一个,轻量级性能高
    2. C#语言联系很紧密,许多框架如Abp都会有默认支持AutoFac,微软的Orchad开源程序使用的就是Autofac
    3. 支持很多的注入方式,除了传统的 构造函数注入,DI容器注入(使用 IServiceProvider 接口的对象) 如方法注入,属性注入,控制器注入 这些特殊的方式
      2.缺点
    4. 传说没有微软自带的 依赖注入 速度快
    AutoFac 几种依赖注入使用方法介绍
    1. 演示绝大部分都是在 Startup.cs 里面进行的,也有一个测试的控制器TestController,重在理解,以下是自己研究的项目源码GitHub地址:

    2. 最基本的注入方式 通过DL容器的方式 一般的容器注入 初始

      1. IServiceCollection serviceDescriptors = new ServiceCollection();
        //指定关系
        serviceDescriptors.AddScoped<ITestAService, TestAService>();
        //build
        ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
        
        //下面是作用域的关系比较
        
        //1.同一个作用域 获取的实例 时同一个
        //var testA = (ITestAService)serviceProvider.GetService<ITestAService>();
        //var testA1 = (ITestAService)serviceProvider.GetService<ITestAService>();
        //var isEq = object.ReferenceEquals(testA, testA1);
        
        //2.再次Build时 范围声明周期 已经发生了变化
        //ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider();
        //var testA2 = (ITestAService)serviceProvider1.GetService<ITestAService>();
        
        //var isEq1 = object.ReferenceEquals(testA1, testA2);
        
        //testA.show();
        
    3. AutoFac容器最简单的使用

      1. //容器构建着
        ContainerBuilder containerBuilder = new ContainerBuilder();
        //指定关系
        containerBuilder.RegisterType<TestAService>().As<ITestAService>();
        //构建
        IContainer container = containerBuilder.Build();
        //获取服务
        ITestAService testA3 = container.Resolve<ITestAService>();
        testA3.show();
        
        
    4. AutoFac容器 默认支持构造函数注入

      1. ContainerBuilder containerBuilder1 = new ContainerBuilder();
        containerBuilder1.RegisterType<TestAService>().As<ITestAService>();
        containerBuilder1.RegisterType<TestBService>().As<ITestBService>();
        IContainer container1 = containerBuilder1.Build();
        ITestBService testB = container1.Resolve<ITestBService>();
        testB.show();
        
    5. AutoFac容器 属性注入 PropertiesAutowired()

      1. ContainerBuilder containerBuilder2 = new ContainerBuilder();
        containerBuilder2.RegisterType<TestAService>().As<ITestAService>();
        containerBuilder2.RegisterType<TestBService>().As<ITestBService>();
        //支持属性注入的方法
        containerBuilder2.RegisterType<TestCService>().As<ITestCService>().PropertiesAutowired();
        IContainer container2 = containerBuilder2.Build();
        
        ITestCService testC = container2.Resolve<ITestCService>();
        testC.show();
        
        
    6. AutoFac 支持的方法注入

      1. ContainerBuilder containerBuilder3 = new ContainerBuilder();
        containerBuilder3.RegisterType<TestAService>().As<ITestAService>();
        containerBuilder3.RegisterType<TestBService>().As<ITestBService>();
        //支持属性注入的方法
        containerBuilder3.RegisterType<TestCService>().As<ITestCService>().PropertiesAutowired();
        //方法注入
        //其中的SetSevice()方法是在 TestDService里面定义的一个方法
        containerBuilder3.RegisterType<TestDService>().OnActivated(a => a.Instance.SetSevice(a.Context.Resolve<ITestAService>())).As<ITestDService>();
        //使用
        IContainer container3 = containerBuilder3.Build();
        ITestDService testD = container3.Resolve<ITestDService>();
        testD.show();
        
    7. AutoFac 声明周期 瞬时(每次获取对象都是一个全新的实例) 示例

    8.  ContainerBuilder containerBuilder4 = new ContainerBuilder();
         containerBuilder4.RegisterType<TestAService>().As<ITestAService>().InstancePerRequest();
      
         			//InstancePerDependency 瞬时
                  //InstancePerLifetimeScope()  范围
                  // InstancePerMatchingLifetimeScope("name名称") *匹配 name* 声明周期范围实例
                  //SingleInstance  单例
                  //InstancePerRequest 每一个请求,一个实例
      
          IContainer container4 = containerBuilder4.Build();
          ITestAService testA4 = container4.Resolve<ITestAService>();
          ITestAService testA5 = container4.Resolve<ITestAService>();
      	//比较
          var IsEq = object.ReferenceEquals(testA4, testA5);
          Console.WriteLine(IsEq);
      
    9. AutoFac 特殊的控制器中使用 属性注入方式

      1. 需要使用两个特性来实现

      2. image

      3. CustomPropertyAttribute 特性用来 当作标识,且声明只能是属性才能使用该特性

      4. CustomPropertySelector 特性是需要给控制器告知哪些属性是可以注入的 (需要一个判断的维度)

      5. 具体代码详见 GitHub 示例

    • 整个项目 使用AutoFac 自动构建 关系

      • 方式一 使用 配置文件 (完全断开对 实体的依赖)

        • 安装 支持的Nuget包
          • Autofac.Extensions.DependencyInjection
          • Autofac.Configuration
        • 内部好像也是用来反射Dll 来实现,感觉配置文件也挺复杂,所以就没有使用这种方案
      • 方式二 使用用反射来实现 ******

        • 1.收钱 需要在ConfigureServices 里面提供 控制器注入的支持

          •  //AutoFac 提供控制器支持
             //1   替换控制器的替换规则
             //1.1 可以指定控制器让 容器来创建
            services.Replace(ServiceDescriptor.Transient<IControllerActivator,ServiceBasedControllerActivator>());
            
          • 需要实现自定义实现ConfigureContainer方法,注意反射注入的方法需要写在这里面,不然没有效果

            • 代码如下

            • /// <summary>
                      /// AutoFac 自己会调用这个方法 进行注册
                      /// 1.负责注册 各种服务
                      /// 2.ServiceCollection 注册的,也同样是可以使用的
                      /// 3.还支持控制器 里面的属性注入
                      /// </summary>
                      /// <param name="builder"></param>
                      public void ConfigureContainer(ContainerBuilder builder)
                      {
                          Assembly serviceDLL = Assembly.Load(new AssemblyName("WebApplicationApi"));
              
                          //1.Service 后缀类的反射 注入
                          var serviceTypes = serviceDLL.GetTypes().Where(t => t.Name.EndsWith("Service") && !t.GetTypeInfo().IsAbstract);
                          foreach (var serviceType in serviceTypes)
                          {
                              //var asdfasf = serviceType.Name;
                              foreach (var interType in serviceType.GetInterfaces())
                              {
                                  var sname = serviceType.Name;
                                  var Iname = interType.Name;
                                  Console.WriteLine($"{sname}--->{Iname}");
                                  builder.RegisterType(serviceType).As(interType).InstancePerDependency()
                                      .AsImplementedInterfaces()//自动以其实现的所有接口类型暴露(包括IDisposable接口)
                                      .InstancePerLifetimeScope()
                                      .PropertiesAutowired();//支持属性注入的方法;
                              }
                          }
              
                          //2   首先需要在Service,里面提供支持 services.Replace(.......)
                          //2.1 控制器实例的注入 
                          var controllerTypes = typeof(Startup).GetTypeInfo().Assembly.DefinedTypes.
                              Where(x => x.IsClass && typeof(ControllerBase).GetTypeInfo().IsAssignableFrom(x)).
                              Select(x => x.AsType()).
                              ToArray();
                          builder.RegisterTypes(controllerTypes)
                              //支持属性注入的方法;
                              //CustomPropertySelector 设置哪些是可以被注入的 (指定特性属性注入的支持)
                              .PropertiesAutowired(new CustomPropertySelector());
              
                      }
              
        • 这样就能直接在控制里面使用了

          • 具体使用如下
            • image

    以上就是AutoFac的一些基本使用方法,欢迎大家讨论,转载请标明原创地址~ 谢谢~~~Bye~

  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/goodluckily/p/15582610.html
Copyright © 2011-2022 走看看