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

基于输入参数返回不同类型对象的工厂实现疑问

解决方案

要解决这个泛型工厂的适配问题,核心是先统一所有Creator的类型标识,让DI能批量注入,再通过非泛型接口做类型中转。具体步骤如下:

1. 新增非泛型基接口

把ICreator<T>的公共能力抽成一个非泛型接口,这样所有泛型Creator都能被统一识别:

// 非泛型基接口,提供统一的类型判断和基础创建能力
interface ICreator
{
    bool CanHandle(string type);
    BaseClass Create();
}

// 泛型接口继承非泛型,保留强类型创建方法
interface ICreator<T> : ICreator where T : BaseClass
{
    new T Create();
}

2. 修改Creator实现类

让每个Creator同时实现泛型和非泛型接口的方法,非泛型方法直接调用泛型版本:

class Creator1 : ICreator<MyClass1>
{
    public bool CanHandle(string type) => type == "type1";

    // 强类型创建方法
    public MyClass1 Create()
    {
        return new MyClass1();
    }

    // 实现非泛型接口的Create,内部转调泛型方法
    BaseClass ICreator.Create() => Create();
}

class Creator2 : ICreator<MyClass2>
{
    public bool CanHandle(string type) => type == "type2";

    public MyClass2 Create()
    {
        return new MyClass2();
    }

    BaseClass ICreator.Create() => Create();
}

3. 实现总工厂类

通过DI注入所有ICreator实例,根据传入的type筛选出对应的Creator,调用创建方法:

class ObjectFactory
{
    private readonly IEnumerable<ICreator> _allCreators;

    // 构造函数注入所有Creator实例
    public ObjectFactory(IEnumerable<ICreator> creators)
    {
        _allCreators = creators;
    }

    // 基础方法:返回BaseClass类型实例
    public BaseClass Create(string type)
    {
        var matchedCreator = _allCreators.FirstOrDefault(c => c.CanHandle(type));
        if (matchedCreator == null)
            throw new ArgumentException($"不支持的类型标识:{type}");
        
        return matchedCreator.Create();
    }

    // 可选:强类型返回方法,适用于明确知道目标类型的场景
    public T Create<T>(string type) where T : BaseClass
    {
        var matchedCreator = _allCreators.OfType<ICreator<T>>().FirstOrDefault(c => c.CanHandle(type));
        if (matchedCreator == null)
            throw new ArgumentException($"类型{typeof(T)}不支持标识:{type}");
        
        return matchedCreator.Create();
    }
}

为什么这么做?

原来的泛型ICreator<T>每个具体类型(比如ICreator<MyClass1>)都是不同的CLR类型,DI容器无法直接批量注入同一“类型族”的实例。通过非泛型基接口统一后,所有Creator都能被收集到IEnumerable<ICreator>中,既保留了强类型创建的优势,又解决了批量筛选和调用的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:25:25