Delphi,如何避免application.CreateForm?

Lud*_*c C 4 delphi dependency-injection spring4d

我使用Spring4d框架 进行依赖注入和其他事情.

在应用程序入口点,我必须创建应用程序"Main"表单.虽然,我不知道其他任何方式

Application.CreateForm(TMainForm, MainForm) 
Run Code Online (Sandbox Code Playgroud)

创造这个.

是否可以使用Spring4d依赖注入创建Main表单?像这样:

MainForm := GlobalContainer.Resolve<IMainForm>;
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*nke 10

使用DI容器注册主窗体时,可以通过将实例传递给DelegateTo方法来指定工厂函数来创建实例.

在我看来,没有必要将主窗体解析为接口,因为它是组合根,它不会被传递到其他任何地方,所以我会像下面那样注册它.

container.RegisterType<TMainForm,TMainForm>.DelegateTo(
  function: TMainForm
  begin
    Application.CreateForm(TMainForm, Result);
  end);
Run Code Online (Sandbox Code Playgroud)

然后你可以解决它的问题

container.Resolve<TMainForm>;
Run Code Online (Sandbox Code Playgroud)

然而,让容器解析表单的好处是它可能会将依赖关系注入其中,这不会发生在这里,因为内部的代码CreateForm创建了实例.这就是在施工后通过容器调用其他方法的可能性.因此,不是像往常一样将依赖项传递给构造函数,而是可以Init向表单类添加一个let say 方法,该表单类获取所需的依赖项[Inject]并向其添加属性.这将告诉容器在创建实例之后调用此方法(在我们的例子中通过传递给DelegateTo方法的工厂函数)并将所有必需的依赖项传递给它.

可以通过容器获取依赖关系的最小空主表单如下所示:

TMainForm = class(TForm)
public
  [Inject]
  procedure Init(...);
end;
Run Code Online (Sandbox Code Playgroud)

  • 我在dpr文件中调用Application.CreateForm看不出任何好处.据推测有一些.我错过了什么? (2认同)
  • @WarrenP 不需要边缘侮辱。如果您对这种方法有抱怨,欢迎在我们的论坛 (https://groups.google.com/forum/#!forum/spring4d) 上与我们讨论 - 也只是因为许多人缺乏 DI 知识直接使用容器,这不是库的错误。我总是告诉人们编写纯 DI 兼容的代码,从而避免诸如字段注入或类似的事情。 (2认同)
  • 在此之前,我还认为应该在任何单元中使用Container来解决依赖关系.这似乎是正确的方法.但是,即使在DI框架上没有任何依赖性,它也会更加清晰.但是,实际上,只有组合根才能使用容器.在其他任何地方,您都不必担心依赖关系.它们就在你身边...... (2认同)