14 Aralık 2023 Perşembe

Örnek DI uygulaması 2-Projenin ve ana bağlantıların oluşturulması

Bu örneği çalıştırabilmek için MS SQL ve Delphi 10 ya da üzeri sürümler kullanmanız gerekmektedir. 

Öncelikle Delphi'de File - New - Windows VCL Application Delphi 'ye tıklayın. Bunun sonucunda yeni bir VCL uygulaması açılacaktır. Bunu DITest adlı bir klasöre yine aynı adlı proje olarak kaydediyoruz. Form'a View.MainForm adını vererek kaydediyoruz. 

Formun üzerine Tool Palette'den Toolbar, StatusBar ve 2 adet TPanel bırakıyoruz. Bunlardan bir panelin Alignment'ı taLeft yapıyoruz, sonra Tool Palette'den bir TSplitter bırakıyoruz formun üzerine ve bunun Alignment'ını da taLeft yapıyoruz. 

2. panelin Alignment'ını taClient yapıyoruz. 

Her iki panelin de Caption özelliğini boş yapıyoruz, yani yazan Panel1 ve Panel2'yi siliyoruz. Ayrıca ben BevelOuter özelliğini de None yapıyorum. 

Soldaki panel üzerine ToolPalette'den TCategoryPanelGroup bırakıyorum. Bunun üzerinde sağ klik yapıp New Panel'e basarak yeni grupçuklar yaratıyorum. Bunları da adlandırıyorum:

  • Stok İşlemleri
  • Alım Siparişleri
  • Alım İşlemleri
  • Satış Siparişleri
  • Satış İşlemleri
Elbette bunlar sadece örnek olarak varlar. Bunların üzerine pek çok madde eklenebilir.
Bu kategori panellerinin üzerinde Add Control/Button seçerek 4'er adet buton ekleyelim ve her birine ad verelim.

MainForm

Şimdi aradaki bağlantıları sağlayan kısımları oluşturmadan önce Frame'leri oluşturalım. Frame'i doğrudan Container'e bağlamayacağımız için onu başka bir sınıfla sarmalamalıyız. Bu sınıflar da her işlem ekranı için bir adet olmalı. Bunlar için öncelikle interface'leri oluşturalım.

unit uInterfaces;

interface
uses Vcl.ExtCtrls;

type
   IDisplayOnPanel = interface
    ['{F2D7E53B-5EB3-4A8F-A12D-E9C9A3F56874}']
    procedure DisplayOnPanel(const aPanel: TPanel);

  end;

implementation

end
Tabloları ekranda gösterecek tüm frame'ler bundan türetilmiş sınıfların içinde yer alacaklar. Bunun ardından stokları göstereceğimiz frame'i oluşturalım.

Önce projeye yeni bir VCL frame ekleyelim, üzerine 2 adet panel koyalım, Panel2'nin Align'ını alBottom ve Panel1'inkini alClient yapalım. Caption'larını kaldıralım, BevelOuter'larını bvNone yapalım.

Panel1'in üzerine bir DBGrid koyalım ve bunun bazı özelliklerini şu şekilde değiştirelim;
-ReadOnly=True
-Align=alClient
-Options.dgEditing=False
-Options.dgRowSelect=True

Frame'e bir TDataSource ekleyelim ve bunu DBGrid'in DataSource özelliğine bağlayalım. Yani
DBGrid1.DataSource := DataSource1;
Sonrasında DBGrid1 üzerine elle stok tablosundaki bazı alanları ekliyoruz (InventoryItemId, ItemCode, ItemName, SpecCode) ve bunların kolon genişliklerini ayarlıyoruz.

Stok liste frame'i


Şimdi bu frame'i sarmak için stok Displayer'ini oluşturalım:
unit uInventoriesDisplayer;

interface
uses System.Classes, uInterfaces, Vcl.Controls, Vcl.ExtCtrls;

type
  TInventoriesDisplayer = class(TInterfacedObject, IDisplayOnPanel)
  public
    procedure DisplayOnPanel(const aPanel: TPanel);
  end;

implementation

{ TInventoriesDisplayer }

procedure TInventoriesDisplayer.DisplayOnPanel(const aPanel: TPanel);
var frm : TframeInventories;
begin
  frm := TframeInventories.Create(aPanel);
  frm.Parent := aPanel;
  frm.Align := alClient;
end;

end.

Burada görüldüğü gibi DisplayOnPanel içerisinden Stok gridini içeren frame'i create ediyoruz ve MainForm'daki client frame'i içerecek olan Panel'in içine yerleştiriyoruz. Ancak datayla ilgili herhangi bir işlem yapmadık henüz.

Şimdi xxxDisplayer ve MainForm arasındaki bağlantıyı oluşturacak Container kaydını yapalım! Bunun için uRegistration adlı bir Unit oluşturacağız.

unit uRegistration;

interface

uses
  Spring.Container, uInterfaces;

procedure RegisterInterfaces;

implementation
uses
      uInventoriesDisplayer
    ;

procedure RegisterInterfaces;
begin
  GlobalContainer.RegisterType<IDisplayOnPanel, TInventoriesDisplayer>('inventories');

  GlobalContainer.Build;
end;

end.


ve bu RegisterInterfaces rutinini MainForm'un OnCreate olayında çağırmamız gerekiyor.

procedure TMainForm.FormCreate(Sender: TObject);
begin
  RegisterInterfaces;
end;
Ve Stoklar düğmesine bastığımızda yapacaği işlemleri de yazalım :
procedure TMainForm.btnStoklarClick(Sender: TObject);
begin
  ViewClientFrame('inventories');
end;

procedure TMainForm.ViewClientFrame(const aFrameName: string);
var
  iScr : IDisplayOnPanel;
  i : integer;
begin
  for i:=pnlForClientFrames.ControlCount-1 downto 0 do
    if pnlForClientFrames.Controls[i] is TFrame then
      pnlForClientFrames.Controls[i].Free;
  iScr := GlobalContainer.Resolve<IDisplayOnPanel>(aFrameName);
  iScr.DisplayOnPanel(pnlForClientFrames);
end;


Burada ViewClientFrame() adlı bir procedure oluşturduk ve event'den ekranın kayıt ismini vererek bunu çağırdık. Bunun nedeni bu işlemin her buton için tekrarlanacağıydı. Bunları tekrar tekrar yazmamak için bu şekilde yazdık.
Şimdi sırada DB connection kısmı var, onu da yazdığımızda çerçeveyi tamamlamış olacağız.
Bunun için önce uInterfaces.pas kod birimine şu interafce'i ekliyoruz;

  IMyConnection = interface
    ['{3AD307A1-E323-4A65-9AE7-B25436A5DC1F}']
    function GetQuery(aSql : String) : TDataset;
  end;

Ve ardından yeni bir Unit içinde bunun uygulamasını yazıyoruz :

unit uMyADOConnection;

interface

uses DB, ADODB, uInterfaces;

type
  TMyADOConnection = class(TInterfacedObject, IMyConnection)
  private
    fConnection : TADOConnection;
  public
    constructor Create(aConnection : TADOConnection);
    function GetQuery(const aSql : String) : TDataset;
  end;

implementation

{ TMyADOConnection }

constructor TMyADOConnection.Create(aConnection : TADOConnection);
begin
  inherited Create;
  fConnection := aConnection;
  fConnection.LoginPrompt := False;
  fConnection.Connected := True;
end;

function TMyADOConnection.GetQuery(const aSql: String): TDataset;
var
  aQuery : TADODataset;
begin
  aQuery := TADODataset.Create(fConnection);
  aQuery.Connection := fConnection;
  aQuery.CommandText := aSql;
  aQuery.Open;
  Result := aQuery;
end;

end.

uRegistration biriminde Connection ile ilgili düzeltmeler yapacağız.
unit uRegistration;

interface

uses
  Spring.Container, uInterfaces;

procedure RegisterInterfaces(aMyConnection : IMyConnection);

implementation
uses
      uInventoriesDisplayer
    ;

procedure RegisterInterfaces(aMyConnection : IMyConnection);
begin
  GlobalContainer.RegisterType<IDisplayOnPanel, TInventoriesDisplayer>('inventories');

  GlobalContainer.RegisterInstance<IMyConnection>(aMyConnection, 'connection');

  GlobalContainer.Build;
end;

end.
MainForm üzerine Tool Palette'den bir TADOConnection ekleyeceğiz. Bunun DB ile bağlantısını kurup OnCreate event'inde bazı değişiklikler yapacağız. 


procedure TMainForm.FormCreate(Sender: TObject);
begin
  myConnection := TMyAdoConnection.Create(ADOConnection1);
  RegisterInterfaces(myConnection);
end;
Son olarak ta View.Inventories.pas'ta yapılandırıcıyı buraya koyacağız ve sonunda şu şekle getireceğiz.

unit View.Inventories;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Vcl.Grids,
  Vcl.DBGrids, Vcl.ExtCtrls,
  Spring.Container,
  uInterfaces;

type
  TframeInventories = class(TFrame)
    Panel1: TPanel;
    Panel2: TPanel;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
  private
    { Private declarations }
  public
    constructor Create(AOwner : TComponent); override;
  end;

implementation

{$R *.dfm}

{ TframeInventories }

constructor TframeInventories.Create(AOwner: TComponent);
var
  aConnection: IMyConnection;
begin
  inherited;
  aConnection := GlobalContainer.Resolve<IMyConnection>('connection', []); //<IMyConnection>;
  DataSource1.DataSet := aConnection.GetQuery('select * from InventoryItem order by InventoryItemId');
end;

end.
Bu halinin kodlarını şu linkten indirebilirsiniz : DITest kodları 









Hiç yorum yok:

Yorum Gönder