【问题标题】:Injecting primitive type in constructor of generic type using Microsoft DI使用 Microsoft DI 在泛型类型的构造函数中注入原始类型
【发布时间】:2022-01-07 23:34:35
【问题描述】:

我正在尝试使用依赖注入来添加具有构造函数参数的通用服务。我需要实现这个,一般来说:

host.Services.AddSingleton<IService>(x => 
    new Service(x.GetRequiredService<IOtherService>(),
                x.GetRequiredService<IAnotherOne>(), 
                ""));

这就是我使用开放泛型所做的工作:

host.Services.AddSingleton(typeof(IGenericClass<>), typeof(GenericClass<>));

我无法使用 opengenerics 添加构造函数参数。这是我要添加DI的类:

public class GenericClass<T> : IGenericClass<T> where T : class, new()
{
    private readonly string _connectionString;
    private readonly IGenericClass2<T> _anotherGenericInterface;
    private readonly IInterface _anotherInterface;
    public GenericClass(
        string connectionString,
        IGenericClass2<T> anotherGenericInterface,
        IInterface anotherInterface)
    {
        _connectionString = connectionString ??
            throw new ArgumentNullException(nameof(connectionString));
        _executer = anotherGenericInterface;
        _sproc = anotherInterface;
    }
}

【问题讨论】:

  • 连接字符串总是一样的吗?
  • 是的,我已经预先运行了一些代码来获取它。 @ChiefTwoPencils

标签: c# asp.net-core dependency-injection .net-5 open-generics


【解决方案1】:

使用 MS.DI,不可能像使用 IService 注册那样使用工厂方法构建开放通用注册。

这里的解决方案是将所有原始构造函数值包装到 Parameter Object 中,这样 DI Container 也可以解析它。例如:

// Parameter Object that wraps the primitive constructor arguments
public class GenericClassSettings
{
    public readonly string ConnectionString;
    
    public GenericClassSettings(string connectionString)
    {
        this.ConnectionString =
            connectionString ?? throw new ArgumentNullExcpetion();
    }
}

GenericClass&lt;T&gt; 的构造函数现在可以依赖于新的参数对象:

public GenericClass(
    GenericClassSettings settings,
    IGenericClass2<T> anotherGenericInterface,
    IInterface anotherInterface)
{
    _connectionString = settings.ConnectionString;
    _executer = anotherGenericInterface;
    _sproc = anotherInterface;
}

这允许您注册新的参数对象和开放通用类:

host.Services.AddSingleton(new GenericClassSettings("my connection string"));

host.Services.AddSingleton(typeof(IGenericClass<>), typeof(GenericClass<>));

【讨论】:

    【解决方案2】:

    您不能使用 Microsoft DI 将参数传递给构造函数。 但是工厂方法允许这样做。 如果要将类型字符串作为参数传递给此构造函数,则需要将字符串注册为服务 - 但此操作可能会导致很多错误,因为许多服务可以具有构造函数字符串参数。 所以我建议你使用Options pattern来传递一个像连接字符串这样的参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多