类型上不满足的构造函数
Unsatisfied constructor on type
使用 Spring4D 的依赖注入框架。
此刻我尝试使用 DynamicAbstractFactories。
在测试中有 2 类 和工厂:
IOrderShipper
和 IOrderShipperFactory
会起作用,
IDocument
和 IDocumentFactory
将失败。
程序 TestDocument 中的代码将引发
Unsatisfied constructor on type: DynamicAbstractFactory.TDocument
我不明白为什么....
我希望有人知道原因,我觉得很愚蠢
program DynamicAbstractFactory;
{$APPTYPE CONSOLE}
uses
System.Sysutils,
Spring.Container;
type
TEnum = (e1, e2, e3, e4, e5);
IDocument = interface
['{CCB718EF-7670-4157-97FF-0E49ACBEB449}']
procedure Show;
end;
IDocumentFactory = interface(IInvokable)
['{73ADE7C1-3119-45B6-B615-04A4079AA581}']
function Create: IDocument; overload;
function Create(ID: integer; DocType: TEnum; Level: integer): IDocument; overload;
end;
IOrderShipper = interface
['{F4653C0C-2C05-4348-A744-3288E520F586}']
procedure Ship;
end;
IOrderShipperFactory = interface(IInvokable)
['{F632D1FB-9C34-48FD-BD72-6BBC436D1B47}']
function Create: IOrderShipper; overload;
function Create(const name: string): IOrderShipper; overload;
function Create(aId: integer; en: TEnum; Level: integer): IOrderShipper; overload;
end;
TOrderShipper = class(TInterfacedObject, IOrderShipper)
private
fName: string;
public
constructor Create; overload;
constructor Create(const name: string); overload;
constructor Create(aId: integer; en: TEnum; Level: integer); overload;
procedure Ship;
end;
TDocument = class(TInterfacedObject, IDocument)
public
constructor Create; overload;
constructor Create(aId: integer; aDocType: TEnum; aLevel: integer); overload;
procedure Show;
end;
constructor TDocument.Create;
begin
inherited Create;
end;
constructor TDocument.Create(aId: integer; aDocType: TEnum; aLevel: integer);
begin
inherited Create;
end;
procedure TDocument.Show;
begin
writeln('Show Document');
end;
constructor TOrderShipper.Create;
begin
Create('default');
end;
constructor TOrderShipper.Create(const name: string);
begin
inherited Create;
fName := name
end;
constructor TOrderShipper.Create(aId: integer; en: TEnum; Level: integer);
begin
Create('Args Enum E'+ (ord(en)+1).ToString);
end;
procedure TOrderShipper.Ship;
begin
Writeln('shipped by: ', fName, ' ');
end;
procedure FillContainer;
begin
GlobalContainer.RegisterType<IOrderShipper, TOrderShipper>;
GlobalContainer.RegisterType<IOrderShipperFactory>.AsFactory;
GlobalContainer.RegisterType<IDocument, TDocument>;
GlobalContainer.RegisterType<IDocumentFactory>.AsFactory;
GlobalContainer.Build;
end;
procedure TestOrder;
var
factory: IOrderShipperFactory;
service: IOrderShipper;
begin
factory := GlobalContainer.Resolve<IOrderShipperFactory>;
service := factory.Create;
service.Ship;
service := factory.Create('Test');
service.Ship;
service := factory.Create(1, TEnum.e5, 3);
service.Ship;
end;
procedure TestDocument;
var
factory: IDocumentFactory;
service: IDocument;
begin
factory := GlobalContainer.Resolve<IDocumentFactory>;
service := factory.Create;
service.Show;
// This call will fail.........
service := factory.Create(1, TEnum.e5, 3);
service.Show;
end;
begin
ReportMemoryLeaksOnShutdown := True;
try
FillContainer;
try
TestOrder;
TestDocument;
except
on E: Exception do
writeln(E.message);
end;
finally
Readln;
end;
end.
注册工厂时,您可以指定参数resolved/matched。默认情况下,这是按名称进行的,这意味着工厂方法中的参数用于查找匹配的构造函数。在您的 IOrderShipperFactory
的情况下,它们与您的 TOrderShipper
构造函数中的参数相同。但在 IDocumentFactory.Create
中,它们与 TDocument.Create
中的并不相同。您可以修复命名,也可以使用 TParamResolution.ByValue
,这样就可以传递来自工厂方法的参数,并在构造函数选择中按类型匹配它们。
使用 Spring4D 的依赖注入框架。
此刻我尝试使用 DynamicAbstractFactories。
在测试中有 2 类 和工厂:
IOrderShipper
和 IOrderShipperFactory
会起作用,
IDocument
和 IDocumentFactory
将失败。
程序 TestDocument 中的代码将引发
Unsatisfied constructor on type: DynamicAbstractFactory.TDocument
我不明白为什么.... 我希望有人知道原因,我觉得很愚蠢
program DynamicAbstractFactory;
{$APPTYPE CONSOLE}
uses
System.Sysutils,
Spring.Container;
type
TEnum = (e1, e2, e3, e4, e5);
IDocument = interface
['{CCB718EF-7670-4157-97FF-0E49ACBEB449}']
procedure Show;
end;
IDocumentFactory = interface(IInvokable)
['{73ADE7C1-3119-45B6-B615-04A4079AA581}']
function Create: IDocument; overload;
function Create(ID: integer; DocType: TEnum; Level: integer): IDocument; overload;
end;
IOrderShipper = interface
['{F4653C0C-2C05-4348-A744-3288E520F586}']
procedure Ship;
end;
IOrderShipperFactory = interface(IInvokable)
['{F632D1FB-9C34-48FD-BD72-6BBC436D1B47}']
function Create: IOrderShipper; overload;
function Create(const name: string): IOrderShipper; overload;
function Create(aId: integer; en: TEnum; Level: integer): IOrderShipper; overload;
end;
TOrderShipper = class(TInterfacedObject, IOrderShipper)
private
fName: string;
public
constructor Create; overload;
constructor Create(const name: string); overload;
constructor Create(aId: integer; en: TEnum; Level: integer); overload;
procedure Ship;
end;
TDocument = class(TInterfacedObject, IDocument)
public
constructor Create; overload;
constructor Create(aId: integer; aDocType: TEnum; aLevel: integer); overload;
procedure Show;
end;
constructor TDocument.Create;
begin
inherited Create;
end;
constructor TDocument.Create(aId: integer; aDocType: TEnum; aLevel: integer);
begin
inherited Create;
end;
procedure TDocument.Show;
begin
writeln('Show Document');
end;
constructor TOrderShipper.Create;
begin
Create('default');
end;
constructor TOrderShipper.Create(const name: string);
begin
inherited Create;
fName := name
end;
constructor TOrderShipper.Create(aId: integer; en: TEnum; Level: integer);
begin
Create('Args Enum E'+ (ord(en)+1).ToString);
end;
procedure TOrderShipper.Ship;
begin
Writeln('shipped by: ', fName, ' ');
end;
procedure FillContainer;
begin
GlobalContainer.RegisterType<IOrderShipper, TOrderShipper>;
GlobalContainer.RegisterType<IOrderShipperFactory>.AsFactory;
GlobalContainer.RegisterType<IDocument, TDocument>;
GlobalContainer.RegisterType<IDocumentFactory>.AsFactory;
GlobalContainer.Build;
end;
procedure TestOrder;
var
factory: IOrderShipperFactory;
service: IOrderShipper;
begin
factory := GlobalContainer.Resolve<IOrderShipperFactory>;
service := factory.Create;
service.Ship;
service := factory.Create('Test');
service.Ship;
service := factory.Create(1, TEnum.e5, 3);
service.Ship;
end;
procedure TestDocument;
var
factory: IDocumentFactory;
service: IDocument;
begin
factory := GlobalContainer.Resolve<IDocumentFactory>;
service := factory.Create;
service.Show;
// This call will fail.........
service := factory.Create(1, TEnum.e5, 3);
service.Show;
end;
begin
ReportMemoryLeaksOnShutdown := True;
try
FillContainer;
try
TestOrder;
TestDocument;
except
on E: Exception do
writeln(E.message);
end;
finally
Readln;
end;
end.
注册工厂时,您可以指定参数resolved/matched。默认情况下,这是按名称进行的,这意味着工厂方法中的参数用于查找匹配的构造函数。在您的 IOrderShipperFactory
的情况下,它们与您的 TOrderShipper
构造函数中的参数相同。但在 IDocumentFactory.Create
中,它们与 TDocument.Create
中的并不相同。您可以修复命名,也可以使用 TParamResolution.ByValue
,这样就可以传递来自工厂方法的参数,并在构造函数选择中按类型匹配它们。