Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

delphi - How to initialize main application form in Spring4D GlobalContainer?

so for instance I have a main form and want to inject a logger instance as private field.

I register the logger

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

I have a private field in my main form

private
   FLogger: ILogger;

All what I want is to make so:

private
   [Inject]
   FLogger: ILogger;

In my DPR file I have typical delphi way to create main form:

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

What should I change in a way of the form creation to have private fields injected properly?

By the way if I resolve the field in Form.OnCreate with GlobalContainer.Resolve it works fine. But I want to avoid using GlobalContainer variable in my forms.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have to register your form to the container as well. This is done like this:

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;

in your main you then write:

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

You could even write a helper for TApplication so you can keep the Application.CreateForm call and don't let the IDE mess up your main from time to time.

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;

You then of course need to make sure your BuildContainer routine does not use that helper (put into a separate registration unit) or you end up in recursion.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...