Üç Katmanlı Mimari ile .NET Windows Uygulamalarına Giriş
Uygulamaların yaşam döngüsünün uzun olması, minimum kod
yazımı, uygulamanın anlaşılır ve geliştirilebilir olması için üç katmanlı
mimarinin artılarından faydalanmak gerekir. Sunum, iş ve veri katmanlarının
olması, uygulamanızı birçok açıdan geliştirir. Gerek güvenlik gerekse de yazılım
mühendisliği yöntemlerinden faydalanma bakımından izlenmesi gereken bir
yoldur.
Üç katmanlı mimarinin en üstünde sunum katmanı(presentation
layer) yatar. Bu katmanda son kullanıcıya gösterilmesi gereken veriler sunulur.
Burada herhangi bir işlem yapılmaz. Kullanıcı ile iletişimde olan katmandır. O
nedenle iyi bir şekilde hazırlanmalı, kullanımı kolay arayüzler ile
sunulmalıdır. Web ortamında kullanıcıların gördüğü HTML sayfaları bu katmana
örnek verilebilir.
İş katmanı(business layer), bir üst katmandır. Sunum
katmanından gelen istekleri hazırlayan ve veri katmanı ile haberleşen yer
burasıdır. Bütün iş kuraları burada bulunur. Bankacılık uygulamalarında yapılan
EFT işlemi için, yeterli bakiye kontrolü, EFT yapılacak hesap geçerliliği gibi
kontrollerin yapıldığı yerdir. Web uygulamalarında sıkça görülen
geçerlilik(validation) kontrolleri kimi zaman sunum katmanına alınır.

Veri katmanı(data layer) iş kurallarından habersiz bir
şekilde kendisinden istenen verileri işler, hazırlar. Bu katman bazen bir XML
dosyası bazen de Oracle gibi DBMS olabilir. Veritabanı içinden bir veri
kümesinin gelmesi bu katman tarafından gerçekleştirilir.
Uygulamalarda bu katmanların belirgin bir ölçüde ayrılmasının
birçok avantajları vardır. Bunların en başında modülerlik yatar. Örneğin üç
katmanlı mimariye uygun bir program oluşturdunuz. Bu uygulama sadece web
üzerinden çalışacak olsun. Aradan belli bir zaman geçtikten sonra aynı projenin
masaüstü uygulamasını da yapmanız gereksin. Üç katmanlı mimaride sadece sunum
katmanını değiştirerek kolaylıkla masaüstü uygulamanızı gerçekleştirebilirsiniz.
Yani web sayfası yerine yapacağınız bir Windows formu işleminizi
tamamlayacaktır. Veya uygulamanızın şuan için MSSQL üzerinde çalıştığını ileride
Oracle’ye geçtiğinizi varsayalım. Yine sadece yapmanız gereken veri katmanını
değiştirmeniz olacaktır. Sürekli değişen ihtiyaçlar göz nünde tutulursa üç
katmanlı mimarinin ne derece önemli olduğu görülecektir.

Yukarıdaki açıklamalar ışığında .NET ile Windows Form
uygulamasının nasıl yapılacağını gösterelim. MS SQL Server 2000 ve C# dili
üzerinde gerçekleştirilecek uygulama, basit bir menü tasarımı olacaktır. Bir
menünün dalları olabilir. Örneğin;
Ürünler
Elektrikli Ürünler
Elektronik Ürünler
Şarj Edilebilen ürünler
Şarj Edilemeyen ürünler
Öncelikle veritabanında Bir tablo oluşturalım:
CREATE TABLE Menu(
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[ParentId] [int] NULL ,
[Name] [nvarchar] (128) NULL ,
[Description] [nvarchar] (512) NULL ,
[CreateDate] [datetime] NULL ,
[ModifyDate] [datetime] NULL
)
Ardından bu tabloya uygun bir sınıf oluşturalım:
public class Menu
{
private int mId;
private int mParentId;
private string mName;
private string mDescription;
private DateTime mCreateDate;
private DateTime mModifyDate;
}
using System;
using System.Data;
using System.Data.SqlClient;
namespace ThreeTierMenu.Data
{
public class DataLayer
{
private string mConnectionString;
public DataLayer( string _connectionString )
{
this.mConnectionString = _connectionString;
}
private SqlConnection GetConnection()
{
return new SqlConnection( this.mConnectionString );
}
public int ExecuteQuery( string _query, SqlParameter[] _params )
{
int Result;
SqlCommand Command = new SqlCommand( _query, GetConnection() );
Command.CommandType = CommandType.Text;
Command.Parameters.Clear();
for(int i = 0; i < _params.Length; i++ )
{
Command.Parameters.Add( _params[i]);
}
Command.Connection.Open();
Result = Command.ExecuteNonQuery();//No Exception Handling. Global Excpt. handling used
Command.Connection.Close();
return Result;
}
public DataTable GetResultSet( string _query, SqlParameter[] _params )
{
SqlCommand Command = new SqlCommand( _query, GetConnection() );
Command.CommandType = CommandType.Text;
Command.Parameters.Clear();
for(int i = 0; i < _params.Length; i++ )
{
Command.Parameters.Add( _params[i]);
}
SqlDataAdapter Adapter = new SqlDataAdapter(Command);
DataSet ResultDataSet = new DataSet();
Adapter.Fill( ResultDataSet );
return ResultDataSet.Tables[0];
}
}
}
using System;
using System.Data;
using System.Data.SqlClient;
namespace ThreeTierMenu.Bussiness
{
public class BussinessLayer
{
private Data.DataLayer mDataHandle;
public BussinessLayer( string _connectionString)
{
this.mDataHandle = new ThreeTierMenu.Data.DataLayer( _connectionString );
}
public int InsertMenu( Menu.Menu _Menu )
{
SqlParameter[] Params = new SqlParameter[3];
Params[0] = new SqlParameter( "@ParentId",SqlDbType.Int );
if( _Menu.ParentId != -1 )
{
Params[0].Value = _Menu.ParentId;
}
else
{
Params[0].Value = System.DBNull.Value;
}
Params[1] = new SqlParameter( "@Name",SqlDbType.NChar );
Params[1].Value = _Menu.Name;
Params[2] = new SqlParameter( "@Description",SqlDbType.NChar );
Params[2].Value = _Menu.Description;
string InsertQuery = "INSERT INTO Menu( ParentId, Name, Description) VALUES(@ParentId, @Name, @Description )";
int Result = this.mDataHandle.ExecuteQuery(InsertQuery, Params );
return Result;
}
public int UpdateMenu( Menu.Menu _Menu )
{
SqlParameter[] Params = new SqlParameter[4];
Params[0] = new SqlParameter( "@Id",SqlDbType.Int );
Params[0].Value = _Menu.Id;
Params[1] = new SqlParameter( "@ParentId",SqlDbType.Int );
if( _Menu.ParentId != -1 )
{
Params[1].Value = _Menu.ParentId;
}
else
{
Params[1].Value = System.DBNull.Value;
}
Params[2] = new SqlParameter( "@Name",SqlDbType.NChar );
Params[2].Value = _Menu.Name;
Params[3] = new SqlParameter( "@Description",SqlDbType.NChar );
Params[3].Value = _Menu.Description;
string UpdateQuery = "UPDATE Menu SET ParentId = @ParentId, Name = @Name, Description = @Description WHERE Id = @Id";
int Result = this.mDataHandle.ExecuteQuery(UpdateQuery, Params );
return Result;
}
public int DeleteMenu( int _MenuId )
{
SqlParameter[] Params = new SqlParameter[1];
Params[0] = new SqlParameter( "@Id",SqlDbType.Int );
Params[0].Value = _MenuId;
string DeleteQuery = "DELETE Menu WHERE Id = @Id";
int Result = this.mDataHandle.ExecuteQuery(DeleteQuery, Params );
return Result;
}
public DataTable GetMenus()
{
SqlParameter[] Params = new SqlParameter[0];
string SelectQuery = "SELECT * FROM Menu";
DataTable ResultSet = this.mDataHandle.GetResultSet(SelectQuery, Params );
return ResultSet;
}
public Menu.Menu GetMenuInfo( int _MenuId )
{
SqlParameter[] Params = new SqlParameter[1];
Params[0] = new SqlParameter( "@Id",SqlDbType.Int );
Params[0].Value = _MenuId;
string SelectQuery = "SELECT * FROM Menu WHERE Id = @Id";
DataTable ResultSet = this.mDataHandle.GetResultSet(SelectQuery, Params );
Menu.Menu ReturnMenu = null;
if( ResultSet.Rows.Count == 0 )
{
return ReturnMenu;
}
else
{
ReturnMenu = new ThreeTierMenu.Menu.Menu();
ReturnMenu.Id = Convert.ToInt32( ResultSet.Rows[0][0].ToString() );
ReturnMenu.Name = ResultSet.Rows[0][2].ToString();
ReturnMenu.ParentId = Convert.ToInt32( ResultSet.Rows[0][1].ToString() );
ReturnMenu.Description = ResultSet.Rows[0][3].ToString();
ReturnMenu.CreateDate = Convert.ToDateTime( ResultSet.Rows[0][4].ToString() );
ReturnMenu.ModifyDate = Convert.ToDateTime( ResultSet.Rows[0][5].ToString() );
return ReturnMenu;
}
}
public DataTable GetParentMenus()
{
SqlParameter[] Params = new SqlParameter[0];
string SelectQuery = "SELECT a.Id, a.Name FROM Menu a";
DataTable ResultSet = this.mDataHandle.GetResultSet(SelectQuery, Params );
return ResultSet;
}
}
}
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace ThreeTierMenu
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MenuForm : System.Windows.Forms.Form
{
#region Private Members
private System.Windows.Forms.TabControl TC_Menu;
private System.Windows.Forms.TabPage TP_Select;
private System.Windows.Forms.TabPage TP_Insert;
private System.Windows.Forms.TabPage TP_Update;
private System.Windows.Forms.TabPage TP_Delete;
private System.Windows.Forms.Button BT_Add;
private System.Windows.Forms.ComboBox CB_ParentId;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox TB_Name;
private System.Windows.Forms.TextBox TB_Description;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.DataGrid DG_Menus;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label LB_Info;
private System.Windows.Forms.Button BT_Delete;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.ComboBox CB_ParentIdUpdate;
private System.Windows.Forms.TextBox TB_DescriptionUpdate;
private System.Windows.Forms.TextBox TB_NameUpdate;
private System.Windows.Forms.Button BT_Update;
private System.Windows.Forms.Button BT_GetUpdate;
private System.Windows.Forms.Button BT_GetDelete;
private System.Windows.Forms.TextBox TB_IdUpdate;
private System.Windows.Forms.TextBox TB_IdDelete;
private Bussiness.BussinessLayer mBussinessHandler;
#endregion Private Members
public MenuForm()
{
string ConnectionString = "Data Source=MENNAN;Initial Catalog=Practise;Integrated Security=SSPI";
this.mBussinessHandler = new ThreeTierMenu.Bussiness.BussinessLayer(ConnectionString);
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.TC_Menu = new System.Windows.Forms.TabControl();
this.TP_Select = new System.Windows.Forms.TabPage();
this.DG_Menus = new System.Windows.Forms.DataGrid();
this.TP_Insert = new System.Windows.Forms.TabPage();
this.TB_Description = new System.Windows.Forms.TextBox();
this.TB_Name = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.CB_ParentId = new System.Windows.Forms.ComboBox();
this.BT_Add = new System.Windows.Forms.Button();
this.TP_Update = new System.Windows.Forms.TabPage();
this.BT_GetUpdate = new System.Windows.Forms.Button();
this.label7 = new System.Windows.Forms.Label();
this.TB_IdUpdate = new System.Windows.Forms.TextBox();
this.TB_DescriptionUpdate = new System.Windows.Forms.TextBox();
this.TB_NameUpdate = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.CB_ParentIdUpdate = new System.Windows.Forms.ComboBox();
this.BT_Update = new System.Windows.Forms.Button();
this.TP_Delete = new System.Windows.Forms.TabPage();
this.BT_Delete = new System.Windows.Forms.Button();
this.LB_Info = new System.Windows.Forms.Label();
this.BT_GetDelete = new System.Windows.Forms.Button();
this.label8 = new System.Windows.Forms.Label();
this.TB_IdDelete = new System.Windows.Forms.TextBox();
this.TC_Menu.SuspendLayout();
this.TP_Select.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.DG_Menus)).BeginInit();
this.TP_Insert.SuspendLayout();
this.TP_Update.SuspendLayout();
this.TP_Delete.SuspendLayout();
this.SuspendLayout();
//
// TC_Menu
//
this.TC_Menu.Controls.Add(this.TP_Select);
this.TC_Menu.Controls.Add(this.TP_Insert);
this.TC_Menu.Controls.Add(this.TP_Update);
this.TC_Menu.Controls.Add(this.TP_Delete);
this.TC_Menu.Dock = System.Windows.Forms.DockStyle.Fill;
this.TC_Menu.Location = new System.Drawing.Point(0, 0);
this.TC_Menu.Name = "TC_Menu";
this.TC_Menu.SelectedIndex = 0;
this.TC_Menu.Size = new System.Drawing.Size(472, 382);
this.TC_Menu.TabIndex = 0;
//
// TP_Select
//
this.TP_Select.Controls.Add(this.DG_Menus);
this.TP_Select.Location = new System.Drawing.Point(4, 22);
this.TP_Select.Name = "TP_Select";
this.TP_Select.Size = new System.Drawing.Size(464, 356);
this.TP_Select.TabIndex = 0;
this.TP_Select.Text = "View Menus";
//
// DG_Menus
//
this.DG_Menus.DataMember = "";
this.DG_Menus.Dock = System.Windows.Forms.DockStyle.Fill;
this.DG_Menus.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.DG_Menus.Location = new System.Drawing.Point(0, 0);
this.DG_Menus.Name = "DG_Menus";
this.DG_Menus.Size = new System.Drawing.Size(464, 356);
this.DG_Menus.TabIndex = 1;
//
// TP_Insert
//
this.TP_Insert.Controls.Add(this.TB_Description);
this.TP_Insert.Controls.Add(this.TB_Name);
this.TP_Insert.Controls.Add(this.label3);
this.TP_Insert.Controls.Add(this.label2);
this.TP_Insert.Controls.Add(this.label1);
this.TP_Insert.Controls.Add(this.CB_ParentId);
this.TP_Insert.Controls.Add(this.BT_Add);
this.TP_Insert.Location = new System.Drawing.Point(4, 22);
this.TP_Insert.Name = "TP_Insert";
this.TP_Insert.Size = new System.Drawing.Size(464, 356);
this.TP_Insert.TabIndex = 1;
this.TP_Insert.Text = "Add Menu";
//
// TB_Description
//
this.TB_Description.Location = new System.Drawing.Point(144, 80);