简体   繁体   English

DI容器无法解析FMX控件

[英]DI container can't resolve FMX controls

I have following project: 我有以下项目:

MyForm unit(just empty form): 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.

App Unit: 应用单元:

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.

And build code: 并构建代码:

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

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

Run BuildProject() causes Error: "Cannot resolve type: TMyForm". 运行BuildProject()会导致错误:“无法解析类型:TMyForm”。 I was testing same configuration on VCL platform and there everything is ok. 我在VCL平台上测试了相同的配置,一切正常。 Do you have any idea what is wrong here? 你知道这里有什么问题吗?

Edit1: I had to change problem description because I was wrong thinking that the problem occurs on both(VCL and FMX) platforms. Edit1:我不得不更改问题描述,因为我错误地认为该问题在两个(VCL和FMX)平台上均会发生。 @RudyVelthuis 's comment showed me that problem is only on FMX platform. @RudyVelthuis的评论向我表明问题仅在FMX平台上。

During registration there are two different kinds of types: 在注册期间,有两种不同类型的类型:

  • component type - meaning the underlying type that is being constructed (typically a class) 组件类型-表示正在构造的基础类型(通常是一个类)
  • service type - a type that can be resolved - this can also be the component type 服务类型-可以解析的类型-也可以是组件类型

When using RegisterType<T> you only specify the component type. 使用RegisterType<T> ,仅指定组件类型。

If you do not explicitly specify a service type for the component type the container will make a best guess. 如果您没有为组件类型明确指定服务类型,则容器将做出最佳猜测。

During the Build it inspects the component type for any interfaces and registers those as service types (the only exception being IComponentReference implemented by TComponent ). Build它检查任何接口组件类型和寄存器的那些业务类型(唯一的例外是IComponentReference通过实现TComponent )。 If it does not find any it will register the class type itself as service type. 如果找不到,它将把类类型本身注册为服务类型。

That usually works with VCL (because of the exclusion of IComponentReference ) but not FMX because there all the classes implement many different interfaces. 这通常适用于VCL(由于排除了IComponentReference ),但不适用于FMX,因为在那里所有类都实现了许多不同的接口。

Using the RegisterType overload with two generic parameters (the first one is the service type, second the component type) or adding one or more Implements calls will explicitly register one or more service type(s) for the component type. RegisterType重载与两个通用参数一起使用(第一个是服务类型,第二个是组件类型)或添加一个或多个Implements调用将为组件类型显式注册一个或多个服务类型。

I'm a little confused, but when I changed: 我有些困惑,但是当我改变时:

GlobalContainer.RegisterType<TMyForm>;

to

GlobalContainer.RegisterType<TMyForm, TMyForm>;

it worked. 有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM