类型上不满意的构造函数

时间:2018-09-03 09:35:48

标签: delphi spring4d

使用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.

1 个答案:

答案 0 :(得分:7)

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