Spring4D中如何为同一IItem接口注册多个自动工厂?
解决Delphi容器注入多个自动工厂到TItemFactory的问题
要给TItemFactory注入对应多个IItem实现的Func<IHost,IItem>工厂数组,核心是为每个命名的IItem实现单独注册对应的命名工厂,再将这些工厂收集为数组注入构造函数。
步骤1:注册命名的IItem实现
先按你已熟悉的方式注册不同的IItem实现:
GlobalContainer.RegisterType<IItem,TItem1>('Item1'); GlobalContainer.RegisterType<IItem,TItem2>('Item2');
步骤2:为每个IItem实现注册对应的命名工厂
默认的RegisterFactory只会绑定无命名的IItem,因此需要为每个命名的IItem单独注册带标识的工厂,确保每个工厂对应正确的Item类型:
// 注册对应TItem1的工厂 GlobalContainer.RegisterFactory<Func<IHost,IItem>>('Item1Factory') .AsFactory(function(const container: TContainer): Func<IHost,IItem> begin Result := function(Host: IHost): IItem begin // 解析命名的TItem1实例,并传入Host参数 Result := container.Resolve<IItem>('Item1', [TValue.From(Host)]); end; end); // 注册对应TItem2的工厂 GlobalContainer.RegisterFactory<Func<IHost,IItem>>('Item2Factory') .AsFactory(function(const container: TContainer): Func<IHost,IItem> begin Result := function(Host: IHost): IItem begin Result := container.Resolve<IItem>('Item2', [TValue.From(Host)]); end; end);
步骤3:注册TItemFactory并注入工厂数组
最后注册TItemFactory时,手动收集所有命名工厂组成数组,注入到构造函数:
GlobalContainer.RegisterType<IItemFactory, TItemFactory> .InjectConstructor(function(const container: TContainer): TArray<Func<IHost,IItem>> begin Result := [ container.Resolve<Func<IHost,IItem>>('Item1Factory'), container.Resolve<Func<IHost,IItem>>('Item2Factory') ]; end);
简化方案(部分容器支持)
如果使用的容器(比如Spring4D)支持自动收集同类型的命名实例为数组,可以简化注册:
// 直接绑定工厂到对应命名的IItem GlobalContainer.RegisterFactory<Func<IHost,IItem>>('Item1').For<IItem>('Item1'); GlobalContainer.RegisterFactory<Func<IHost,IItem>>('Item2').For<IItem>('Item2'); // 容器自动收集所有Func<IHost,IItem>实例组成数组注入构造函数 GlobalContainer.RegisterType<IItemFactory, TItemFactory>;
关键说明
你之前觉得“为多个自动工厂命名毫无意义”,其实命名是必要的——每个命名工厂对应一个具体的IItem实现,容器需要通过名称区分不同的工厂逻辑,才能正确生成对应TItem1或TItem2的实例。
内容的提问来源于stack exchange,提问作者Richard Shuck
相关产品推荐
相关产品推荐

