2

我在使用 Spring4D 框架的 GlobalContainer 创建从另一个继承的自定义类对象时遇到问题。

父类:

type
  TVSPSection = class ( TInterfacedObject, IVSPSection )

  private
        _id : Integer;
        _organization : IDirectoryObject;

        function GetId () : Integer;
        procedure SetId ( const value : Integer );
        function GetOrganization () : IDirectoryObject;
        procedure SetOrganization ( const value : IDirectoryObject );

  public
        property Id : Integer read GetId write SetId;
        property Organization : IDirectoryObject read GetOrganization write SetOrganization;

end;

...

initialization

  GlobalContainer.RegisterType<TVSPSection>.Implements<IVSPSection>.
        InjectField ( '_organization' )
        ;

后代阶层:

type
  TVSPSeismicSection = class ( TVSPSection, IVSPSeismicSection, IInterface )

  private
        _report : IReport;

        function GetReport () : IReport;
        procedure SetReport ( const value : IReport );

  public
        property Report : IReport read GetReport write SetReport;

end;

...

initialization

  GlobalContainer.RegisterType<TVSPSeismicSection>.Implements<IVSPSeismicSection>.
        InjectField ( '_report' )
        ;

end.

我尝试创建 TVSPSeismicSection 对象:

_seismicSection : IVSPSeismicSection;
_seismicSection := GlobalContainer.Resolve<IVSPSeismicSection>;

接下来,我尝试访问(父类的)“组织”字段并获得访问冲突错误。

 _seismicSection.Organization.Id := -1;    <- exception is here

那么,问题是如何告诉父类使用 GlobalContainer 解析器来启动它的字段?也许通过 DelegateTo 方法,但如何?

我发现的一种方法是在后代类的构造函数中启动父字段,如下所示:

constructor TVSPSeismicSection.Create ();
begin

  Organization := GlobalContainer.Resolve<IDirectoryObject>;

end;

但这违反了依赖注入范式,因为我必须在后代类中包含其他类(IDirectoryObject)。

4

1 回答 1

1

有几种方法,这取决于哪种方法最好。通常,必需的依赖项应作为构造函数参数传递,可选的依赖项应通过属性注入传递。

因此,如果您向您的类添加一个带有IDirectoryObject参数的构造函数TVSPSection,如果容器知道如何解析,则它能够满足该参数IDirectoryObject

这通常是最简洁的方式,因为关于使用 DI 容器的一条规则是编写仍然与 DI 容器无关的代码,并将容器仅用作工具而不是依赖项。

如果您想保留属性注入,那么在该Inject属性上使用该属性应该可以工作(不要忘记添加Spring.Container.Common该属性的用途),就像在注册中指定 InjectProperty 一样(虽然可能我会避免字段注入,因为那是唯一可行的通过 RTTI 而不是常规代码 - 请参阅上一段)。

于 2015-04-10T06:49:04.333 回答