Delphi,如何避免application.CreateForm?

Delphi,如何避免application.CreateForm?,delphi,dependency-injection,spring4d,Delphi,Dependency Injection,Spring4d,我正在使用依赖注入和其他东西 在应用程序入口点中,我必须创建应用程序“Main”表单。不过,我不知道还有什么别的办法 Application.CreateForm(TMainForm, MainForm) 来创建这个 是否可以使用Spring4d依赖项注入创建主窗体?像这样: MainForm := GlobalContainer.Resolve<IMainForm>; MainForm:=GlobalContainer.Resolve; 然后将其设置为打开应用程序时显示的表

我正在使用依赖注入和其他东西

在应用程序入口点中,我必须创建应用程序“Main”表单。不过,我不知道还有什么别的办法

Application.CreateForm(TMainForm, MainForm) 
来创建这个

是否可以使用Spring4d依赖项注入创建主窗体?像这样:

MainForm := GlobalContainer.Resolve<IMainForm>;
MainForm:=GlobalContainer.Resolve;

然后将其设置为打开应用程序时显示的表单?

当您向DI容器注册主表单时,您可以通过将其传递给
DelegateTo
方法来指定工厂函数来创建实例

在我看来,没有必要将主窗体解析为接口,因为它是组合根,并且不会传递到任何其他地方,所以我将按照下面的方式注册它

container.RegisterType<TMainForm,TMainForm>.DelegateTo(
  function: TMainForm
  begin
    Application.CreateForm(TMainForm, Result);
  end);

最终,必须为主窗体调用
Application.CreateForm(…)
。否则VCL框架将不知道有一个主窗体。你真的在为主表单做DI吗?这真的是个好主意吗?我觉得这好像是一个货物崇拜。不是个好主意。你必须知道什么时候该用,什么时候不该用。TApplication需要您调用CreateForm。这是规定。你不能打破它。您可以让应用程序的主窗体为空,并使用spring动态组合其所有内容。但是你不能修改VCL。如果你不打算有多个
IMainForm
,我看不出添加更多间接寻址的意义。在KISS、YAGNI和DI之间的任何战斗中,让KISS和YAGNI获胜。我看不到dpr文件中call Application.CreateForm的任何好处。大概有一些。我错过了什么?如果您只调用
Application.CreateForm
,那么容器就不会发挥作用,因此不会发生DI(您必须自己调用
MainForm.Init(container.Resolve,container.Resolve,…)
。此外,容器也没有将
MainForm
实例注册到自身,因此您不能将其注入依赖于它的类。@WarrenP不需要边界侮辱。如果您对这种方法有意见,欢迎您在我们的论坛上与我们讨论()——这也是因为许多缺乏DI知识的人直接使用容器,这不是库的错。我总是告诉人们编写与DI完全兼容的代码,从而避免像字段注入或类似的事情。以前,我还认为容器应该用于任何单元来解决依赖关系。这似乎是正确的做法。但当您甚至对DI框架没有任何依赖性时,它就是事件清理器。但是,实际上,只有在组合根中才应该使用容器。在其他任何地方,您都不必担心依赖关系。它们只是供您使用的…有一种方法可以使用容器解析代码中的DEP,那就是服务定位器模式。它用于逐步重构遗留代码以使用DI。但是如果你真的遵循DI原则,你最终就不需要它了。
container.Resolve<TMainForm>;
TMainForm = class(TForm)
public
  [Inject]
  procedure Init(...);
end;