5

たとえば、メインフォームがあり、ロガーインスタンスをプライベートフィールドとして挿入したいとします。

ロガーを登録します

GlobalContainer.RegisterType<TCNHInMemoryLogger>.Implements<ILogger>;

メインフォームにプライベートフィールドがあります

private
   FLogger: ILogger;

私が望むのは、そうするだけです:

private
   [Inject]
   FLogger: ILogger;

私のDPRファイルには、メインフォームを作成するための典型的なデルファイの方法があります:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(Tfrm_CNH, frm_CNH);
  Application.Run;
end.

プライベート フィールドを適切に挿入するには、フォーム作成の方法で何を変更する必要がありますか?

ちなみに、Form.OnCreate のフィールドを GlobalContainer.Resolve で解決すると、正常に動作します。しかし、フォームで GlobalContainer 変数を使用することは避けたいと思います。

4

1 に答える 1

9

フォームもコンテナに登録する必要があります。これは次のように行われます。

procedure BuildContainer(const container: TContainer);
begin
  container.RegisterType<ILogger, TCNHInMemoryLogger>;
  container.RegisterType<TForm8, TForm8>.DelegateTo(
    function: TForm8
    begin
      Application.CreateForm(TForm8, Result);
    end);
  container.Build;
end;

メインで次のように記述します。

begin
  BuildContainer(GlobalContainer);
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  frm_CNH := GlobalContainer.Resolve<Tfrm_CNH>;
  Application.Run;
end.

TApplication のヘルパーを作成して、Application.CreateForm の呼び出しを保持し、IDE がメインをときどき混乱させないようにすることもできます。

type
  TApplicationHelper = class helper for TApplication
    procedure CreateForm(InstanceClass: TComponentClass; var Reference);
  end;

procedure TApplicationHelper.CreateForm(InstanceClass: TComponentClass;
  var Reference);
begin
  if GlobalContainer.HasService(InstanceClass.ClassInfo) then 
    TObject(Reference) := GlobalContainer.Resolve(InstanceClass.ClassInfo).AsObject
  else
    inherited CreateForm(InstanceClass, Reference);
end;

もちろん、BuildContainer ルーチンがそのヘルパーを使用しない (別の登録ユニットに入れる) ことを確認する必要があります。そうしないと、再帰になってしまいます。

于 2014-06-19T11:17:44.700 に答える