类型不满意的构造函数

问题描述 投票:1回答:1

使用Spring4D的依赖注入框架。

我尝试使用DynamicAbstractFactories。在测试是2个类和工厂:IOrderShipperIOrderShipperFactory将工作,IDocumentIDocumentFactory将失败。

程序TestDocument中的代码将引发

类型不满意的构造函数: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.
delphi spring4d
1个回答
7
投票

注册工厂时,您可以指定参数的解析/匹配方式。默认情况下,这是名称,这意味着工厂方法中的参数用于查找匹配的构造函数。在你的IOrderShipperFactory的情况下,它们与你的TOrderShipper构造函数上的参数相同。但在IDocumentFactory.Create,他们与TDocument.Create上的那些不同。您可以修复命名,也可以使用TParamResolution.ByValue,然后只需将参数传递给工厂方法,并在构造函数选择中按类型匹配。

© www.soinside.com 2019 - 2024. All rights reserved.