DI容器无法解析FMX控件

时间:2017-09-19 13:35:05

标签: delphi firemonkey spring4d

我有以下项目:

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()会导致错误:“无法解析类型:TMyForm”。我在VCL平台上测试相同的配置,一切都很好。你知道这里有什么问题吗?

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

2 个答案:

答案 0 :(得分:1)

在注册过程中,有两种不同的类型:

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

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

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

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

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

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

答案 1 :(得分:-1)

我有点困惑,但是当我改变时:

GlobalContainer.RegisterType<TMyForm>;

GlobalContainer.RegisterType<TMyForm, TMyForm>;

它有效。