我已经使用依赖注入测试了我自己的类,现在我必须将它实现到生产中。以下是我班级和相关界面的摘录:
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。
答案 0 :(得分:1)
在您显示的代码中,TNewStrategy
不是来自TComponent
,因此无法在设计时将其置于TForm
。您必须在运行时创建它,在这种情况下,您可以访问其构造函数并可以将ThirdyPartDBTable1
传递给它,例如:
procedure TForm1.FormCreate(Sender: TObject);
begin
NewStrategy := TNewStrategy.Create(ThirdyPartDBTable1);
end;
但是,如果TNewStrategy
是设计时可用的TComponent
后代,如果您更改{{1},则可以在设计时将ThirdyPartDBTable1
与NewStrategy
相关联暴露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.