DI 容器无法解析 FMX 控件

DI container can't resolve FMX controls

我有以下项目:

MyForm 单元(只是空表格):

unit uMyForm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;

type
  TMyForm = class(TForm)
  end;

implementation

{$R *.fmx}

end.

应用单位:

unit App;

interface

uses
    uMyForm,
    Spring.Container;

type
    TApp = class
    private
        _myForm: TMyForm;
    public
        [Inject]
        constructor Create(myForm: TMyForm);
    end;

implementation

uses
  System.SysUtils;

{ TApp }

constructor TApp.Create(myForm: TMyForm);
begin
    _myForm := myForm;
end;

end.

构建代码:

procedure BuildProject;
begin
    GlobalContainer.RegisterType<TApp>;
    GlobalContainer.RegisterType<TMyForm>;
    GlobalContainer.Build;

    _app := GlobalContainer.Resolve<TApp>;
end;

运行 BuildProject() 导致错误:"Cannot resolve type: TMyForm"。我在 VCL 平台上测试相同的配置,一切正常。你知道这里出了什么问题吗?

Edit1:我不得不更改问题描述,因为我错误地认为问题发生在两个(VCL 和 FMX)平台上。 @RudyVelthuis 的评论告诉我问题只出现在 FMX 平台上。

我有点迷茫,但是当我改变的时候:

GlobalContainer.RegisterType<TMyForm>;

GlobalContainer.RegisterType<TMyForm, TMyForm>;

成功了。

注册时有两种类型:

  • 组件类型 - 表示正在构造的基础类型(通常是 class)
  • 服务类型-可以解析的类型-这也可以是组件类型

使用 RegisterType<T> 时,您只需指定组件类型。

如果您没有明确指定组件类型的服务类型,容器将做出最佳猜测。

Build 期间,它检查任何接口的组件类型并将它们注册为服务类型(唯一的例外是由 TComponent 实现的 IComponentReference)。如果没有找到,它将把 class 类型本身注册为服务类型。

这通常适用于 VCL(因为排除了 IComponentReference)但不适用于 FMX,因为所有 classes 都实现了许多不同的接口。

使用带有两个通用参数的 RegisterType 重载(第一个是服务类型,第二个是组件类型)或添加一个或多个 Implements 调用将显式注册一个或多个服务类型(s) 组件类型。