.NET IoC 容器(三)Autofac

2024-06-01 1315阅读

目录

  • .NET IoC 容器(三)Autofac
    • Autofac
    • Nuget 安装
    • 实现DI
      • 定义接口
      • 定义实现类
      • 依赖注入
      • 注入方式
        • 构造函数注入 | 属性注入 | 方法注入
        • 注入实现
        • 接口注册
          • 重复注册
          • 指定参数注册
          • 生命周期
            • 默认生命周期
            • 单例生命周期
            • 每个周期范围一个生命周期
            • 依赖配置
              • Nuget
              • 配置文件
              • AOP
                • Nuget安装
                • 定义接口、实现类
                • 定义切面
                • 容器配置
                • 参考资料

                  .NET IoC 容器(三)Autofac

                  Autofac

                  Autofac 是一个用于 .NET 应用程序的依赖注入 (Dependency Injection, DI) 容器。它帮助开发人员管理对象的创建和生命周期,使得依赖项的注入更加灵活和可维护。以下是 Autofac 的主要功能和特性概述:

                  依赖注入 (Dependency Injection)

                  Autofac 允许你通过构造函数、属性或方法注入依赖项。这样,你可以轻松地将对象的依赖关系传递给需要它们的类,从而提高代码的可测试性和可维护性。

                  模块化设计 (Modular Design)

                  Autofac 支持模块化设计,可以将相关的依赖项注册逻辑分组到模块中。这使得大型应用程序的配置更加简洁和易于管理。

                  生命周期管理 (Lifecycle Management)

                  Autofac 提供多种对象生命周期管理方式,例如单例 (Singleton)、每次请求 (Instance Per Dependency)、每个生命周期范围 (Instance Per Lifetime Scope) 等,允许你精确控制对象的创建和销毁时机。

                  注册与解析 (Registration and Resolution)

                  Autofac 通过流畅的 API 提供了多种注册组件的方式。你可以注册类型、实例、工厂方法,甚至通过扫描程序集自动注册组件。此外,Autofac 的解析功能支持构造函数参数注入、命名参数注入等高级特性。

                  支持 AOP (Aspect-Oriented Programming)

                  Autofac 与 AOP 框架(如 Castle Windsor)集成,支持横切关注点(如日志记录、事务管理)的处理,从而使业务逻辑代码更加简洁。

                  集成支持

                  Autofac 与许多流行的 .NET 库和框架集成良好,包括 ASP.NET Core、WCF、Web API、MVC 等。通过这些集成,Autofac 可以轻松地管理 web 应用程序中的依赖项。

                  扩展性

                  Autofac 具有很高的扩展性,可以通过自定义注册源、生命周期、解析器等方式扩展其功能,以满足特定应用的需求。

                  Nuget 安装

                  .NET IoC 容器(三)Autofac

                  实现DI

                  定义接口

                  internal interface IComputer
                  {
                  }
                  
                  internal interface IKeyboard
                  {
                  }
                  
                  internal interface IMouse
                  {
                  }
                  
                  internal interface IPerson
                  {
                      IComputer Computer { get; set; }
                      IKeyboard Keyboard { get; set; }
                      IMouse Mouse { get; set; }
                      void Work();
                  }
                  

                  定义实现类

                  internal class ConstructBase
                  {
                      public ConstructBase() 
                      {
                          Console.WriteLine($"{this.GetType().Name} - 被构造了");
                      }
                  }
                  
                  internal class LenovoComputer : ConstructBase, IComputer
                  {
                      public LenovoComputer() : base() { }
                  }
                  
                  internal class TogarKeyboard : ConstructBase, IKeyboard
                  {
                      public TogarKeyboard() : base() { }
                  }
                  
                  internal class LogitechMouse : ConstructBase, IMouse
                  {
                      public LogitechMouse() : base() { }
                  }
                  
                  internal class Programmer : ConstructBase, IPerson
                  {
                      public IComputer Computer { get; set; }
                      public IKeyboard Keyboard { get; set; }
                      public IMouse Mouse { get; set; }
                      public Programmer(IComputer computer, IKeyboard keyboard, IMouse mouse) : base()
                      {
                          Computer = computer;
                          Keyboard = keyboard;
                          Mouse = mouse;
                      }
                      public void Work()
                      {
                          Console.WriteLine("Programmers are building software...");
                      }
                  }
                  

                  依赖注入

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  var container = builder.Build();
                  IPerson programmer = container.Resolve();
                  programmer.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  Zhy.IoC.Autofac.Programmer - 被构造了
                  Programmers are building software...
                  

                  注入方式

                  构造函数注入 | 属性注入 | 方法注入

                  定义特性用来筛选属性注入

                  public class InjectPropertyAttribute : Attribute
                  {
                  }
                  

                  定义实现类

                  public class Gamer : ConstructBase, IPerson
                  {
                      public IComputer Computer { get; set; }
                      [InjectProperty]
                      public IKeyboard Keyboard { get; set; }
                      public IMouse Mouse { get; set; }
                      public Gamer(IComputer computer) : base()
                      {
                          Computer = computer;
                      }
                      public void Inject(IMouse mouse)
                      {
                          Mouse = mouse;
                      }
                      public void Work()
                      {
                          Console.WriteLine("The player is playing...");
                      }
                  }
                  

                  注入实现

                  // 注入顺序(与编码顺序无关):构造函数注入 > 属性注入 > 方法注入
                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType()
                      // 方法注入
                      .OnActivating(e =>
                      {
                          IMouse mouse = e.Context.Resolve();
                          e.Instance.Inject(mouse);
                      })
                      // 属性注入
                      .PropertiesAutowired((g, o) => g.Name == "Keyboard")
                      // 构造函数注入
                      .UsingConstructor(typeof(IComputer))
                      .As();
                  var container = builder.Build();
                  IPerson gamer = container.Resolve();
                  gamer.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.Gamer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  The player is playing...
                  

                  结果

                  注入顺序:构造函数注入 > 属性注入 > 方法注入

                  接口注册

                  重复注册

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType()
                      // 方法注入
                      .OnActivating(e =>
                      {
                          IMouse mouse = e.Context.Resolve();
                          e.Instance.Inject(mouse);
                      })
                      // 属性注入
                      .PropertiesAutowired((g, o) => g.Name == "Keyboard")
                      // 构造函数注入
                      .UsingConstructor(typeof(IComputer))
                      .As();
                  var container = builder.Build();
                  IPerson programmer = container.Resolve();
                  programmer.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.Gamer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  The player is playing...
                  

                  调换Gamer和Programmer的注册顺序:

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType()
                      // 方法注入
                      .OnActivating(e =>
                      {
                          IMouse mouse = e.Context.Resolve();
                          e.Instance.Inject(mouse);
                      })
                      // 属性注入
                      .PropertiesAutowired((g, o) => g.Name == "Keyboard")
                      // 构造函数注入
                      .UsingConstructor(typeof(IComputer))
                      .As();
                  builder.RegisterType().As();
                  var container = builder.Build();
                  IPerson programmer = container.Resolve();
                  programmer.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  Zhy.IoC.Autofac.Programmer - 被构造了
                  Programmers are building software...
                  

                  结论

                  同一接口多次注册时,后注册的会覆盖前面注册的,若需要实现多重注册,需要指定名称

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType().As();
                  builder.RegisterType()
                      // 方法注入
                      .OnActivating(e =>
                      {
                          IMouse mouse = e.Context.Resolve();
                          e.Instance.Inject(mouse);
                      })
                      // 属性注入
                      .PropertiesAutowired((g, o) => g.Name == "Keyboard")
                      // 构造函数注入
                      .UsingConstructor(typeof(IComputer))
                      .Named("person");
                  builder.RegisterType().Named("programmer");
                  var container = builder.Build();
                  IPerson programmer = container.ResolveNamed("programmer");
                  IPerson person = container.ResolveNamed("person");
                  programmer.Work();
                  person.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  Zhy.IoC.Autofac.Programmer - 被构造了
                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.Gamer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  Programmers are building software...
                  The player is playing...
                  

                  指定参数注册

                  修改接口

                  internal interface IMouse
                  {
                      string Type { get; set; }
                  }
                  

                  修改实现类

                  internal class LogitechMouse : ConstructBase, IMouse
                  {
                      public LogitechMouse() : base() { }
                      public LogitechMouse(string type) : base()
                      {
                          Type = type;
                      }
                      public string Type { get; set; }
                  }
                  

                  注入

                  var builder = new ContainerBuilder();
                  builder.RegisterType().WithParameter("type","502").As();
                  var container = builder.Build();
                  IMouse mouse = container.Resolve();
                  Console.WriteLine("mouse type: " + mouse.Type);
                  

                  输出

                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  mouse type: 502
                  

                  生命周期

                  Instance Per Dependency(默认) 每次请求组件时都会创建一个新的实例。这是默认的生命周期管理模式。

                  builder.RegisterType().As();
                  

                  Singleton 在整个容器生命周期内,只有一个实例。

                  builder.RegisterType().As().SingleInstance();
                  

                  Instance Per Lifetime Scope 在每个生命周期范围内,共享一个实例。每个生命周期范围都会创建一个新的实例,但在该范围内共享该实例。

                  builder.RegisterType().As().InstancePerLifetimeScope();
                  

                  Instance Per Matching Lifetime Scope 在特定的生命周期范围内共享实例,需要指定标记。

                  builder.RegisterType().As().InstancePerMatchingLifetimeScope("my-scope");
                  

                  Instance Per Request 通常用于 web 应用程序,在每个 HTTP 请求期间共享一个实例。

                  builder.RegisterType().As().InstancePerRequest();
                  

                  Externally Owned 组件由外部代码管理生命周期,Autofac 不会在容器释放时释放该实例。

                  builder.RegisterType().As().ExternallyOwned();
                  

                  Instance Per Dependency 每次依赖请求时都会创建一个新实例。

                  builder.RegisterType().As().InstancePerDependency();
                  

                  默认生命周期

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As();
                  var container = builder.Build();
                  IComputer computer0 = container.Resolve();
                  IComputer computer1 = container.Resolve();
                  Console.WriteLine("computer0: " + computer0.GetHashCode());
                  Console.WriteLine("computer1: " + computer1.GetHashCode());
                  Console.WriteLine($"computer0 == computer1: {computer0 == computer1}");
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  computer0: 32347029
                  computer1: 22687807
                  computer0 == computer1: False
                  

                  单例生命周期

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As().SingleInstance();
                  var container = builder.Build();
                  IComputer computer0 = container.Resolve();
                  IComputer computer1 = container.Resolve();
                  Console.WriteLine("computer0: " + computer0.GetHashCode());
                  Console.WriteLine("computer1: " + computer1.GetHashCode());
                  Console.WriteLine($"computer0 == computer1: {computer0 == computer1}");
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  computer0: 32347029
                  computer1: 32347029
                  computer0 == computer1: True
                  

                  每个周期范围一个生命周期

                  var builder = new ContainerBuilder();
                  builder.RegisterType().As().InstancePerLifetimeScope();
                  var container = builder.Build();
                  IComputer computer0 = container.Resolve();
                  using (var scope = container.BeginLifetimeScope())
                  {
                      IComputer computer1 = scope.Resolve();
                      IComputer computer2 = scope.Resolve();
                      Console.WriteLine("computer0: " + computer0.GetHashCode());
                      Console.WriteLine("computer1: " + computer1.GetHashCode());
                      Console.WriteLine("computer2: " + computer2.GetHashCode());
                      Console.WriteLine($"computer0 == computer1: {computer0 == computer1}");
                      Console.WriteLine($"computer1 == computer2: {computer1 == computer2}");
                  }
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  computer0: 32347029
                  computer1: 22687807
                  computer2: 22687807
                  computer0 == computer1: False
                  computer1 == computer2: True
                  

                  依赖配置

                  Nuget

                  .NET IoC 容器(三)Autofac

                  配置文件

                  Json

                  {
                    "components": [
                      {
                        "type": "Zhy.IoC.Autofac.LenovoComputer,Zhy.IoC.Autofac",
                        "services": [
                          {
                            "type": "Zhy.IoC.Core.IComputer,Zhy.IoC.Core"
                          }
                        ],
                        "autoActivate": true,
                        "instanceScope": "singleinstance"
                      },
                      {
                        "type": "Zhy.IoC.Autofac.TogarKeyboard,Zhy.IoC.Autofac",
                        "services": [
                          {
                            "type": "Zhy.IoC.Core.IKeyboard,Zhy.IoC.Core"
                          }
                        ],
                        "autoActivate": true,
                        "instanceScope": "singleinstance"
                      },
                      {
                        "type": "Zhy.IoC.Autofac.LogitechMouse,Zhy.IoC.Autofac",
                        "services": [
                          {
                            "type": "Zhy.IoC.Core.IMouse,Zhy.IoC.Core"
                          }
                        ],
                        "parameters": {
                          "places": 4
                        },
                        "autoActivate": true,
                        "instanceScope": "singleinstance"
                      },
                      {
                        "type": "Zhy.IoC.Autofac.Programmer,Zhy.IoC.Autofac",
                        "services": [
                          {
                            "type": "Zhy.IoC.Core.IPerson,Zhy.IoC.Core"
                          }
                        ],
                        "autoActivate": true,
                        "instanceScope": "singleinstance"
                      }
                    ]
                  }
                  

                  XML

                  
                  	
                  		Zhy.IoC.Autofac.LenovoComputer,Zhy.IoC.Autofac
                  		
                  	
                  	
                  		Zhy.IoC.Autofac.TogarKeyboard,Zhy.IoC.Autofac
                  		
                  	
                  	
                  		Zhy.IoC.Autofac.LogitechMouse,Zhy.IoC.Autofac
                  		
                  	
                  	
                  		Zhy.IoC.Autofac.Programmer,Zhy.IoC.Autofac
                  		
                  	
                  
                  

                  调用

                  var config = new ConfigurationBuilder();
                  config.AddJsonFile("DI-Autofac.json");
                  // config.AddXmlFile("DI-Autofac.xml");
                  var module = new ConfigurationModule(config.Build());
                  var builder = new ContainerBuilder();
                  builder.RegisterModule(module);
                  var container = builder.Build();
                  IPerson programmer = container.Resolve();
                  programmer.Work();
                  

                  输出

                  Zhy.IoC.Autofac.LenovoComputer - 被构造了
                  Zhy.IoC.Autofac.TogarKeyboard - 被构造了
                  Zhy.IoC.Autofac.LogitechMouse - 被构造了
                  Zhy.IoC.Autofac.Programmer - 被构造了
                  Programmers are building software...
                  

                  AOP

                  Nuget安装

                  .NET IoC 容器(三)Autofac

                  定义接口、实现类

                  public interface IMyService
                  {
                      void DoWork();
                  }
                  
                  public void DoWork()
                  {
                      Console.WriteLine("Doing work...");
                  }
                  

                  定义切面

                  using Castle.DynamicProxy;
                  public class LoggingInterceptor : IInterceptor
                  {
                      public void Intercept(IInvocation invocation)
                      {
                          Console.WriteLine($"Invoking method {invocation.Method.Name} at {DateTime.Now}");
                          invocation.Proceed();
                          Console.WriteLine($"Method {invocation.Method.Name} has completed at {DateTime.Now}");
                      }
                  }
                  

                  容器配置

                  var builder = new ContainerBuilder();
                  builder.Register(c => new LoggingInterceptor());
                  builder.RegisterType()
                         .As()
                         .EnableInterfaceInterceptors()
                         .InterceptedBy(typeof(LoggingInterceptor));
                  var container = builder.Build();
                  var service = container.Resolve();
                  service.DoWork();
                  

                  输出

                  Invoking method DoWork at 2024/5/30 16:49:34
                  Doing work...
                  Method DoWork has completed at 2024/5/30 16:49:34
                  

                  参考资料

                  IOC容器之Unity与AutoFac_unity autofac-CSDN博客

                  Autofac/src/Autofac at develop · autofac/Autofac (github.com)

                  控制容器的反转和依赖关系注入模式 (martinfowler.com)

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]