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

Delphi Spring4D中如何用工厂类与属性实现IDog多实例?

问题解答:通过工厂接口为IDog创建不同实现

问题分析

你遇到的运行时错误**“未找到IDog类型的默认实现”**,核心原因是DI容器无法识别你在IDogFactory方法上标注的[TTola]、[TRudy]属性——容器不知道这些方法要对应哪个已注册的IDog命名实现,而你又没有注册IDog的默认实现,因此抛出找不到默认实现的错误。

明确结论:完全可以通过工厂接口为单个接口创建不同实现,只需让容器明确每个工厂方法对应哪个具体实现即可。

解决方案

从代码中的IInvokable、AsFactory等特征判断你使用的是Spring4D框架,只需将工厂方法上的类属性替换为容器支持的命名标记属性,关联你之前注册的Tola和Rudy命名实现即可:

修改后的核心代码

type
  IDog = interface
    function GetName: string;
    procedure Test;
  end;

  // 使用Spring4D的Named属性标记工厂方法对应的实现名称
  IDogFactory = interface(IInvokable)
    [Named('Tola')]
    function CreateTola: IDog;
    [Named('Rudy')]
    function CreateRudy: IDog;
  end;

  // 其余类定义保持不变
  IFamillyDog = interface
    function Dogs: IList<IDog>;
    function Count: Integer;
  end;

  TTola = class(TInterfacedObject, IDog)
  public
    constructor Create;
    function GetName: string;
    procedure Test;
  end;

  TRudy = class(TInterfacedObject, IDog)
  public
    constructor Create;
    function GetName: string;
    procedure Test;
  end;

  TFamillyDog = class(TInterfacedObject, IFamillyDog)
  private
    fDogs: IList<IDog>;
    function Dogs: IList<IDog>;
    function Count: Integer;
  public
    constructor Create(aFactory: IDogFactory);
  end;

注册代码无需修改

C.RegisterType<IDog, TTola>('Tola');
C.RegisterType<IDog, TRudy>('Rudy');
C.RegisterType<IFamillyDog, TFamillyDog>;
C.RegisterType<IDogFactory>.AsFactory;

原理说明

  1. 你已经通过RegisterType<IDog, TTola>('Tola')和RegisterType<IDog, TRudy>('Rudy')完成了IDog接口的命名注册,为同一个接口绑定了两个不同的实现类,并分别命名为Tola和Rudy。
  2. 在工厂接口的方法上添加[Named('Tola')]属性后,DI容器在生成工厂实现时,会自动关联到对应名称的IDog实现:调用CreateTola会返回TTola实例,调用CreateRudy会返回TRudy实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:47:26