使用Spring4d,您可以注册自定义工厂
aContainer.RegisterInstance<TFunc<string, TMyObject>>(function(aName : string):TMyObject
begin
Result := TMyObject.Create(aName);
end);
通过这种方式,我相信,对于从TComponent
继承的每个依赖,想要传递所有者的人都会这样做
// Registrations
aContainer.RegisterInstance<TFunc<TComponent, TMyObject>>(function(Owner : TComponent):TMyObject
begin
Result := TMyObject.Create(Owner);
end);
// Then in code
constructor TMyClass.Create(aFctry : TFunc<TComponent, TMyObject>);
begin
fObj := aFctry(Self);
end;
或者也可以做
aContainer.RegisterType<TMyObject, TMyObject>;
// In code
constructor TMyClass.Create(aObj : TMyObject);
begin
fObj := aObj;
InsertComponent(aObj);
end;
但是,这很容易出错/添加代码只是为了传递给所有者。是否有一种内置的方法来获取一个工厂,将TComponent作为参数,而不必事先在容器中注册它?
因为我经常使用
constructor MyObject.Create(aDep : TFunc<TMyDep>);
不注册TFunc<TMyDep>
依赖项,只注册TMyDep
类型。
可以传递类似
的内容constructor MyObject.Create(aDep : TFunc<TComponent, TMyDep>);
无需在容器中注册?
答案 0 :(得分:0)
据我所知,如果没有注册,这是不可能的。
但是,使用来自IFactory<T,TResult>
的不同Spring.Container.Common
接口可以摆脱1-4参数的手动工厂实现,这将在注册时由DI容器自动实现。< / p>
所以你会这样注册:
aContainer.RegisterType<TMyObject>;
aContainer.RegisterType<IFactory<TComponent, TMyObject>>.AsFactory;
像这样注册工厂,不需要您的实施 - 容器将为您解决。
这意味着,只要您需要TMyObject
的实例,就不再直接请求它(来自容器)。相反,您确实请求IFactory<TComponent, TMyObject>
的实例,其中TComponent
是TMyObject
构造函数接受的唯一参数。
作为使用另一个类TSomeClass
的构造函数注入的用法的示例,(其中TSomeClass
也是TComponent
后代),它将如下所示:
constructor TSomeClass.Create(const AMyObjectFactory: IFactory<TComponent, TMyObject>);
begin
fMyObjectInstance := AMyObjectFactory(Self);
end;
至少对我来说,这让事情变得更容易。
答案 1 :(得分:0)
如果我理解正确,你会试着避免这样的常规代码:
aContainer.RegisterInstance<TFunc<TComponent, TMyFirstObject>>(function(Owner : TComponent):TMyFirstObject
begin
Result := TMyFirstObject.Create(Owner);
end);
aContainer.RegisterInstance<TFunc<TComponent, TMySecondObject>>(function(Owner : TComponent):TMySecondObject
begin
Result := TMySecondObject.Create(Owner);
end);
aContainer.RegisterInstance<TFunc<TComponent, TMyThirdObject>>(function(Owner : TComponent):TMyThirdObject
begin
Result := TMyThirdObject.Create(Owner);
end);
好吧,您可以使用过程 RegisterComponentDescendant 定义帮助程序类,它将为您创建结构,因此您编写的代码将是这样的:
aContainer.RegisterComponentDescendant<TMyFirstObject>;
aContainer.RegisterComponentDescendant<TMySecondObject>;
aContainer.RegisterComponentDescendant<TMyThirdObject>;
并像以前一样做。 Helper类的定义如下:
TContainerHelper = class helper for TContainer
public
procedure RegisterComponentDescendant<TMyObject: TComponent>;
end;
及其实施:
procedure TContainerHelper.RegisterComponentDescendant <TMyObject>;
begin
self.RegisterInstance<TFunc<TComponent, TMyObject>>(
function(Owner : TComponent):TMyObject
begin
Result := TMyObject.Create(Owner);
end);
end;