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;
原理说明
- 你已经通过
RegisterType<IDog, TTola>('Tola')和RegisterType<IDog, TRudy>('Rudy')完成了IDog接口的命名注册,为同一个接口绑定了两个不同的实现类,并分别命名为Tola和Rudy。 - 在工厂接口的方法上添加
[Named('Tola')]属性后,DI容器在生成工厂实现时,会自动关联到对应名称的IDog实现:调用CreateTola会返回TTola实例,调用CreateRudy会返回TRudy实例。
内容的提问来源于stack exchange,提问作者Tomasz Bojara
相关产品推荐
相关产品推荐

