.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~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM