3

使用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>);

无需在容器中注册?

4

2 回答 2

3

据我所知,没有注册是不可能的。

但是,有一种方法可以摆脱使用不同IFactory<T,TResult>接口的 1-4 个参数的手动工厂实现Spring.Container.Common,这将在注册时由 DI 容器自动实现。

所以你会像这样注册:

aContainer.RegisterType<TMyObject>;
aContainer.RegisterType<IFactory<TComponent, TMyObject>>.AsFactory;

像这样注册工厂,不需要你自己的实现——容器会为你解决它。

这意味着,每当您需要 的实例时TMyObject,您不再直接请求它(从容器中)。相反,您确实请求了一个实例IFactory<TComponent, TMyObject>,其中TComponentTMyObject构造函数接受的唯一参数。

作为使用来自另一个类的构造函数注入的示例TSomeClass,(其中TSomeClass也是一个TComponent后代)它看起来如下所示:

constructor TSomeClass.Create(const AMyObjectFactory: IFactory<TComponent, TMyObject>);
begin
  fMyObjectInstance := AMyObjectFactory(Self);
end;

至少对我来说,这让事情变得容易多了。

于 2015-12-15T21:18:28.950 回答
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;
于 2015-12-16T09:53:19.777 回答