问题描述
所以我有一个主窗体,想要注册一个记录器实例作为私有域。
我注册了记录器
GlobalContainer.RegisterType< TCNHInMemoryLogger> .Implements< ILogger> ;;
我的主窗体中有一个私人字段
private
FLogger:ILogger;
我想要的是这样做:
private
[Inject]
FLogger:ILogger;
在我的DPR文件中,我有典型的delphi方式来创建主窗体:
begin
Application.Initialize;
Application.MainFormOnTaskbar:= True;
Application.CreateForm(Tfrm_CNH,frm_CNH);
Application.Run;
结束。
应该怎样改变表单创建方式,使私有字段正确注入?
顺便说一句,如果我使用GlobalContainer.Resolve解析Form.OnCreate中的字段,它可以正常工作。但是我想避免在我的表单中使用GlobalContainer变量。
您还必须将表单注册到容器。这样做是这样的:
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;
结束你的主要内容是
begin
BuildContainer(GlobalContainer);
Application.Initialize;
Application.MainFormOnTaskbar:= True;
frm_CNH:= GlobalContainer.Resolve< Tfrm_CNH> ;;
Application.Run;
结束。
你甚至可以为TApplication编写一个帮助器,所以你可以保留Application.CreateForm调用,不要让IDE不时地弄乱你的主题。
键入
TApplicationHelper = TApplication的类助手
程序CreateForm(InstanceClass:TComponentClass; var Reference);
结束
程序TApplicationHelper.CreateForm(InstanceClass:TComponentClass;
var Reference);
begin
如果GlobalContainer.HasService(InstanceClass.ClassInfo)then
TObject(Reference):= GlobalContainer.Resolve(InstanceClass.ClassInfo).AsObject
else
继承CreateForm (InstanceClass,Reference);
结束然后你当然需要确保你的BuildContainer例程不使用那个帮助器(放在一个单独的内容中)注册单位)或您最终递归递交。
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.
解决方案 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.
这篇关于如何在Spring4D GlobalContainer中初始化主申请表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!