使用 Microsoft DI 在泛型构造函数中注入基本类型

Injecting primitive type in constructor of generic type using Microsoft DI

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

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

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

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

我无法使用 opengenerics 添加构造函数参数。这是 class 我要添加 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;
    }
}

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

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

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

// 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<T> 的构造函数现在可以依赖于新的参数对象:

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

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

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

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