当前位置:   article > 正文

.Net Core AutoFac 使用方法讲解大全,具体详细使用知识总结

.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();
      2. //指定关系
      3. serviceDescriptors.AddScoped<ITestAService, TestAService>();
      4. //build
      5. ServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
      6. //下面是作用域的关系比较
      7. //1.同一个作用域 获取的实例 时同一个
      8. //var testA = (ITestAService)serviceProvider.GetService<ITestAService>();
      9. //var testA1 = (ITestAService)serviceProvider.GetService<ITestAService>();
      10. //var isEq = object.ReferenceEquals(testA, testA1);
      11. //2.再次Build时 范围声明周期 已经发生了变化
      12. //ServiceProvider serviceProvider1 = serviceDescriptors.BuildServiceProvider();
      13. //var testA2 = (ITestAService)serviceProvider1.GetService<ITestAService>();
      14. //var isEq1 = object.ReferenceEquals(testA1, testA2);
      15. //testA.show();
  3. AutoFac容器最简单的使用

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

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

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

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

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

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

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

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

    4. 具体代码详见 GitHub 示例

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

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

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

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

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

          • 代码如下

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

        • 具体使用如下

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/141380
推荐阅读
相关标签
  

闽ICP备14008679号