Newsgroup: it.comp.lang.delphi
Titolo: Svincolare il datamodule dal form (uses)

ho un Form ed un DataModule, entrambi puntano ad un'Interfaccia,
lo scopo e' creare il datamodule dal form1, senza dover usare "Uses unit2".
vedo il metodo create esposto nell'interfaccia, ma non e' accessibile.
Il compilatore non vede i metodi della unit2.
//Form
//----
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
Unit3,
  StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FBusLogic: IBlTest;
    { Private declarations }
  public
    { Public declarations }
    property BusLogicT: IBlTest read FBusLogic write FBusLogic;
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var TmpForm: TForm1;
begin
    if TmpForm = nil then
       TmpForm := TForm1.Create(nil);
    ShowModal;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
    if BusLogicT = nil then
        BusLogicT.Crea;
    BusLogicT.Conteggio;
end;
end.
//datamodule
//----------
unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
Unit3;
type
  //classe deriva da TDataModule e dalla classe interfaccia
  TDataModule2 = class(TDataModule, IBlTest)
  private
    { Private declarations }
  public
    { Public declarations }
    //constructor Create (AOwner: TComponent); override;
    procedure Crea;
    procedure Conteggio;
  end;
var
  DataModule2: TDataModule2;
implementation
{$R *.DFM}
{ TDataModule2 }
procedure TDataModule2.Conteggio;
var iCont: integer;
begin
    iCont := iCont +1 ;
    ShowMessage(InttOstr(iCont));
end;
procedure TDataModule2.Crea;
begin
    TdataModule2.Create(nil);
end;
end.
//interfaccia
//-----------
unit Unit3;
interface
    type IBlTest = interface(IUnknown)
    ['{E3212F2B-6AA6-4A72-A358-CB2F8153BD3C}']
    procedure Crea;
    procedure Conteggio;
    end;
implementation
end.

lo scopo e' creare il datamodule dal form1, senza dover usare "Uses unit2".
Non puoi farlo. Se la form deve creare il datamodule, la form deve
conoscere il datamodule. 

 Il compilatore non vede i metodi della unit2.
...come e' giusto che sia! :)
Per disaccoppiare le due classi io ricorrerei ad una factory.
Devi creare una terza classe che ha due metodi. Uno per gestire una 
lista di oggetti registrati, l'altro per creare oggetti partendo da un 
nome generico:
procedure registraoggetto(nome:string, classe:TDatamoduleClass)
begin
   Lista.AddObject( nome, Classe );
end;
function creaoggetto(nome:string) : TDataModule;
begin
   i := Lista.IndexOf( nome );
   Result := TDataModuleClass( Lista.Objects(i) ).Create( self );
end;
In questo modo dentro a unit2 puoi "registrare" la classe che ti 
interessa assegnandogli un nome. Tipicamente nel'initialization.
   Factory.RegistraOggetto( 'dm2', TDataModule2 );
da dentro Unit1 e' possibile creare un oggetto semplicemente usando un 
nome, senza bisogno di includere unit2. Naturalmente deve essere 
conosciuto da entrambe le classi quale sia il nome da usare:
   dm := Factory.creaoggetto( 'dm2' );
Il vantaggio di questo schema e' che le classi sono disaccoppiate e 
posso anche sostituire il datamodule con un altro, registrando una 
diversa classe nella factory basta che usi lo stesso nome che viene 
usato dalla form per crearlo.
ciao
Giacomo