You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#依赖注入:泛型工厂的抽象类型注册问题

问题根源

C#泛型默认是不变的——即使ThingA实现了IThing,IThingFactory<ThingA>也无法隐式转换为IThingFactory<IThing>,除非你将泛型接口声明为协变(适用于仅作为输出的泛型参数)。

解决方案

方案1:将泛型工厂接口改为协变

修改IThingFactory的定义,在泛型参数前添加out关键字(仅当泛型参数仅出现在返回值等输出位置时可用):

// 协变泛型工厂接口
public interface IThingFactory<out TThing> where TThing : IThing
{
    TThing Create();
}

此时MyThingFactory<ThingA>可以直接转换为IThingFactory<IThing>,依赖注入注册代码可正常编写:

// 注册时直接绑定抽象与具体实现
services.AddSingleton<IThingFactory<IThing>, MyThingFactory<ThingA>>();

之后你就能在业务代码中注入IThingFactory<IThing>,调用Create()方法得到ThingA实例。

方案2:通过适配器/非泛型接口适配(无法修改原接口时)

如果无法修改原泛型接口的协变属性,可以新增一个非泛型的抽象工厂接口作为统一入口:

// 非泛型抽象工厂
public interface IThingFactory
{
    IThing Create();
}

// 适配器类,将泛型工厂适配为非泛型接口
public class ThingAFactoryAdapter : IThingFactory
{
    private readonly MyThingFactory<ThingA> _innerFactory;

    public ThingAFactoryAdapter(MyThingFactory<ThingA> innerFactory)
    {
        _innerFactory = innerFactory;
    }

    public IThing Create() => _innerFactory.Create();
}

注册时先注册具体泛型工厂,再注册适配器:

services.AddSingleton<MyThingFactory<ThingA>>();
services.AddSingleton<IThingFactory, ThingAFactoryAdapter>();

业务代码中直接注入IThingFactory即可获取ThingA实例。

方案3:直接注册工厂委托

如果不需要额外接口,可以直接通过委托简化注册:

services.AddSingleton<IThingFactory<IThing>>(sp => 
    new MyThingFactory<ThingA>());

内容的提问来源于stack exchange,提问作者John Freebs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:07