将类传递给接口

时间:2014-02-19 23:02:22

标签: delphi interface

我已经使用依赖注入测试了我自己的类,现在我必须将它实现到生产中。以下是我班级和相关界面的摘录:

  ITableDB = interface
    ['{171DE959-8604-4CD3-ACEA-ACCE15E95621}']
    procedure Close;
    procedure Open;
    ...
  end;

  TNewStrategy=class(TObject)
  private
    FTableDB: ITableDB
    .....   
  public
    constructor Create (ATableDB: ITableDB....)
  end;

而不是模拟和存根我现在必须为类提供真实的对象。这些是我在设计时以表格形式放置的许多第三部分组件。这里有一个例子:

type
  TForm1 = class(TForm)
    ThirdyPartDBTable1: ThirdyPartDBTable;
    NewStrategy: TNewStrategy;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

如何将ThirdyPartDBTable1传递给TNewStrategy.Create?我尝试了以下代码:

  TMyThirdyPartDBTable = class(ThirdyPartDBTable, IITableDB)
  public
    procedure Close;
    procedure Open;
    ...
  end;

但是当我尝试将ThirdyPartDBTable1: ThirdyPartDBTable更改为ThirdyPartDBTable1: TMYhirdyPartDBTable;时,编译器会将引用TMYhirdyPartDBTable更改回ThirdyPartDBTable。

2 个答案:

答案 0 :(得分:1)

在您显示的代码中,TNewStrategy不是来自TComponent,因此无法在设计时将其置于TForm。您必须在运行时创建它,在这种情况下,您可以访问其构造函数并可以将ThirdyPartDBTable1传递给它,例如:

procedure TForm1.FormCreate(Sender: TObject);
begin
  NewStrategy := TNewStrategy.Create(ThirdyPartDBTable1);
end;

但是,如果TNewStrategy是设计时可用的TComponent后代,如果您更改{{1},则可以在设计时将ThirdyPartDBTable1NewStrategy相关联暴露TNewStrategy属性而不是在构造函数中传递它,例如:

ITableDB

只要TNewStrategy = class(TComponent) private FTableDB: ITableDB ..... public constructor Create(AOwner: TComponent); override; published property TableDB: ITableDB read FTableDB write FTableDB; end; 实现ThirdyPartDBTable,那么Object Inspector和DFM流将允许它。

更新:,因为ITableDB未实现ThirdPartyDBTable,您可以使用拦截器类来实现它,例如:

ITableDB

答案 1 :(得分:0)

您不能通过在表单声明中修改它来更改您在设计时放置的组件的类,IDE拥有表单上部公共部分中的声明。

您可以在运行时创建派生组件,或者将其安装在运行时包和register with the component library中。对于单个时间作业或测试目的,您可以使用插入器类。在下面的示例中,我使用了TPanel,因为我没有ThirdyPartDBTable,所以请务必在测试表单上放置一个面板。为简洁起见,省略了'Close'方法。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  ITableDB = interface
    ['{171DE959-8604-4CD3-ACEA-ACCE15E95621}']
    procedure Open;
  end;

  TPanel = class(extctrls.TPanel, ITableDB)
  public
    procedure Open;
  end;

  TNewStrategy=class(TObject)
  private
    FTableDB: ITableDB;
  public
    constructor Create(ATableDB: ITableDB);
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    NewStrategy: TNewStrategy;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TPanel }

procedure TPanel.Open;
begin
  ShowMessage('Open what?');
end;

{ TNewStrategy }

constructor TNewStrategy.Create(ATableDB: ITableDB);
begin
  FTableDB := ATableDB;
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  NewStrategy := TNewStrategy.Create(Panel1 as ITableDB);
  NewStrategy.FTableDB.Open;
end;

end.