2

Spring4D Framework の 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>;

次に、(親クラスの)「Organization」フィールドにアクセスしようとすると、アクセス違反エラーが発生します。

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

問題は、親クラスに GlobalContainer リゾルバーを使用してフィールドを開始するように指示する方法です。多分 DelegateTo メソッド経由ですが、どうやって?

私が見つけた1つの方法は、次のように子孫クラスのコンストラクターで親フィールドを開始することです:

constructor TVSPSeismicSection.Create ();
begin

  Organization := GlobalContainer.Resolve<IDirectoryObject>;

end;

しかし、これは依存性注入パラダイムに違反しています。追加のクラス (IDirectoryObject) を子孫クラスに含める必要があるからです。

4

1 に答える 1

1

いくつかの方法があり、どれが最適かによって異なります。通常、必要な依存関係はコンストラクター引数として渡し、オプションの依存関係はプロパティ インジェクションによって渡す必要があります。

IDirectoryObjectしたがって、クラスに引数を取るコンストラクターを追加するTVSPSectionと、解決方法がわかっている場合、コンテナーはその引数を満たすことができますIDirectoryObject

DI コンテナーの使用に関する 1 つのルールは、DI コンテナーにとらわれずにコードを記述し、コンテナーを依存関係としてではなくツールとして使用することであるため、通常はこれが最もクリーンな方法です。

プロパティの注入を維持したい場合は、登録で InjectProperty を指定するのと同じように、Injectそのプロパティの属性を使用して機能する必要があります (その属性の使用に追加することを忘れないでください) (可能な限り、フィールドの注入は避けます。Spring.Container.Common通常のコードではなく RTTI による - 前の段落を参照)。

于 2015-04-10T06:49:04.333 に答える