为通用工厂注册 C# Dep 注入

问题描述 投票:0回答:1

我正在尝试注册一个可以发出东西的工厂,这样做是为了我可以使用 DI 请求最抽象的版本,然后在注册时决定实际使用哪些东西的组合。

代码:

// The thing

public interface IThing
{
    void DoSomething();
}

public class ThingA : IThing
{
    public void DoSomething() => throw new NotImplementedException();
}

public class ThingB : IThing
{
    public void DoSomething() => throw new NotImplementedException();
}

// The factory

public interface IThingFactory<TThing> where TThing : IThing
{
    TThing CreateThing();
}

public class MyThingFactory<TThing> : IThingFactory<TThing> where TThing : IThing
{
    public TThing CreateThing() => throw new NotImplementedException();
}

如果我按如下方式注册并使用它们,它就可以工作:

Services.AddSingleton<IThingFactory<ThingA>, MyThingFactory<ThingA>>();
...
var factory = ServiceProvider.GetRequiredService<IThingFactory<ThingA>>();
// factory is a MyThingFactory<ThingA>

我真正想做的是注册一些东西,以便我可以请求

IThingFactory<IThing>
,但例如,以下定义无法编译:

Services.AddSingleton<IThingFactory<IThing>, MyThingFactory<ThingA>>();

“MyThingFactory”类型不能用作类型参数 泛型类型或方法中的“TImplementation” 'ServiceCollectionServiceExtensions.AddSingleton(IServiceCollection)'。没有隐式引用 从“MyThingFactory”到“ITingFactory”的转换

不清楚如何注册。

c# generics .net-core dependency-injection
1个回答
0
投票

如果您使用

out
关键字在界面上启用协变,您将能够注册该服务。

//                              +--- Add this
//                              |
public interface IThingFactory<out TThing> where TThing : IThing
{
    TThing CreateThing();
}

然后您可以从

IThingFactory<ThingA>
隐式转换为
IThingFactory<IThing>
,这将允许注册类型。像这样:

Services.AddSingleton<IThingFactory<IThing>, MyThingFactory<ThingA>>();
© www.soinside.com 2019 - 2024. All rights reserved.