I have following project:
MyForm unit(just empty form):
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". I was testing same configuration on VCL platform and there everything is ok. 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. @RudyVelthuis 's comment showed me that problem is only on FMX platform.
During registration there are two different kinds of types:
When using RegisterType<T>
you only specify the component type.
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
). 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.
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.