【问题标题】:Dependency injection in my singleton class .NET Core我的单例类 .NET Core 中的依赖注入
【发布时间】:2021-09-14 00:20:09
【问题描述】:

我在将传递给我的 Asegurador 类的构造函数的依赖项注入时遇到问题。

当我要实例化时,_instance = new Asegurador();我没有构造函数(IGeneralRepository)需要的参数,请问如何解决?

请注意,我的 Asegurador 类是单例。

private Asegurador(IGeneralRepository generalRepository)
    {
        _token = GetTokenAsync().Result;
        _repository = generalRepository;
    }
    public static Asegurador Instance
    {
        get
        {
            if (_instance == null)
            {
                _local = System.Environment.GetEnvironmentVariable("SEGUROS_LOCAL") ?? "local";
                _instance = new Asegurador();
            }
            return _instance;
        }
    }

【问题讨论】:

  • 依赖注入的全部意义在于你永远不会写new Asegurador(...),你要求容器给你一个Asegurador的实例,它会帮你解决。跨度>
  • 单例的意义在于,只要你想使用它,就可以随时获取相同的实例。在 DI 容器中将类注册为单例可以做同样的事情,但不必保留静态字段以确保其生命周期跨越整个运行。
  • 依赖注入是一种应用于易失性依赖的实践。由于其行为和依赖关系,您的AseguradorVolatile Dependency,因此您在此处尝试应用 DI 是正确的。 The Singleton pattern should only be used either from within the Composition Root or when the Dependency is Stable.
  • 答案对我来说并不完全清楚,我想要的是将 IGeneralRepository generalRepository 依赖项注入到我的 Asegurador 类中。问题是当我想创建新的 Asegurador() 类时,因为我目前没有 generalRepository 对象。

标签: .net-core dependency-injection singleton


【解决方案1】:

使用 DI 容器时,您可以(并且应该)让它负责处理依赖项的生命周期

.Net core 的依赖注入让您可以为您的服务定义 3 个不同的生命周期 (Docs):

  • Transient:每次注入时都会重新创建一个临时服务
  • Scoped:为每个请求创建一次作用域服务
  • 单例:单例在整个应用程序生命周期内创建一次。

实现您想要做的事情的最佳方法如下:

  • 修改您的 Asegurador 类,使其具有公共构造函数并摆脱静态 Instance 属性

    public class Asegurador {
        public Asegurador(IGeneralRepository generalRepository)
        {
           _token = GetTokenAsync().Result; //I know too few about it but I would try to pass it as a dependency as well
           _repository = generalRepository;
        }
    }
    
  • 而不是调用 Asegurador.Instance 在客户端类中注入依赖项

     public class IUseTheAsegurador {
         private Asegurador _asegurador;
         public IUseTheAsegurador(Asegurador asegurador)
         {
           _asegurador = asegurador;
         }
     }
    
  • 在 Startup.cs 的 DI 中注册所有内容:

     public void ConfigureServices(IServiceCollection services)
     {
        ...
        services.AddSingleton<Asegurador>();
        services.AddScoped<IUseAsegurador>(); //This can be Singleton or Transient as well, depending on your needs
        ...
     }
    

我(实际上很多人 :D)更喜欢这种方法,因为它把保证单个实例的责任留给了 DI,还因为让您可以更轻松地为客户端类(示例中的 IUseTheAsegurador)编写单元测试方式。

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2020-11-20
    • 2016-05-22
    • 1970-01-01
    • 2023-02-24
    • 2021-10-23
    相关资源
    最近更新 更多