2014-02-19 8 views
1

Я протестировал собственный класс с помощью инъекции зависимостей, и теперь я должен реализовать его в производстве. Ниже приводится выдержка из моего класса и соответствующего интерфейса:Прохождение классов к интерфейсам

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

Как последняя попытка не работает? –

+0

Извините, это была только опечатка в вопросе здесь. Все еще не работает. –

+0

Последняя попытка компилируется, но компилятор все еще меняет ссылку, как упоминалось выше. Теперь я удалил часть, вызывающую путаницу. –

ответ

0

Вы не можете изменить класс компонента, который вы указали во время разработки, изменив его в объявлении формы, IDE владеет декларациями в верхней публичной части формы.

Вместо этого вы можете создать производный компонент во время выполнения или установить его в пакет времени выполнения и register with the component library. Для одноразового задания или для целей тестирования вы можете использовать класс интерполятора. В приведенном ниже примере я использовал TPanel, так как у меня нет ThirdyPartDBTable, поэтому не забудьте положить панель в тестовую форму. Также для краткости также опущен метод «Закрыть».

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. 
+0

. Моя идея - найти систему, которая будет использоваться регулярно для всех форм и в производстве, которая позволяет передавать компоненты, размещенные на форме во время разработки, в мой класс, который принимает только интерфейсы в конструктор. Кажется, решение, которое вы предлагаете, не должно быть общей практикой, поэтому мне было интересно, как программисты решают эту проблему. –

+0

@pio - Самый логичный подход, как мне кажется, заключается в разработке собственного набора компонентов. Но на самом деле мне никогда не приходилось решать такую ​​проблему. –

1

В коде вы показали, TNewStrategy не является производным от TComponent, поэтому он не может быть помещен на TForm во время разработки. Вы должны создать его во время выполнения, в этом случае у вас есть доступ к его конструктору и может передавать ThirdyPartDBTable1 к нему, например:

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

Однако, если TNewStrategy были TComponent потомком доступны во время разработки, вы можете связать 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 орудия ITableDB, то это позволит инспектору объекта и потоку DFM.

Update: поскольку ThirdPartyDBTable не реализует ITableDB, вы можете использовать класс перехватчика для его реализации, например:

+0

моя проблема ThirdyPartDBTable не реализует ITableDB изначально, потому что это компонент третьей части. ThirdyPartDBTable1 помещается в форму во время разработки, но я не могу передать ее TNewStrategy.Create, потому что последний принимает только классы с реализованным ITableDB. Кажется, единственное решение - избавиться от компонентов в форме, создать потомка этого компонента и реализовать ITableDB, создать эти компоненты во время выполнения и, наконец, передать их в TNewStrategy.Create ( –

+1

Поскольку вы работаете в Delphi, написание классы перехватчиков были бы более легким подходом, тогда вам не нужно удалять существующие компоненты из формы, вы можете расширить их функциональность во время компиляции. –

+0

Ваше обновление - это то, что я привел в моем ответе. на самом деле не предлагал его использовать. Dunno, это похоже на ненужный взлом для использования в производственном коде для меня (вместо регистрации и замены компонентов). –

Смежные вопросы