Bu makalede, öncelikle ADO.NET ve ASP.NETi bir kaç cümle ile ele aldıktan sonra, nesneye dayalı programlama hakkındaki temel teriminolojileri ele alacağız ve ardından, veri-iş-sunum olmak üzere üç ana katmandan oluşan basit bir örnek uygulama geliştireceğiz. Makalenin amacı, bu terimlerin tamamını kavratmak değil, sadece 3Nlayer(3 katmanlı uygulama) modelini, okuyucunun zihninde şekillendirmektir. Nesneye dayalı programlamaya dair teriminoloji, konunun kavranmasına zemin hazırlamak amacıyla ele alınmıştır. Veri katmanı, sadece bir stored proceduree indirgenmiştir. Sunum katmanı olarak, aspx(ASP.NET) sayfaları kullanılmıştır.
Giriş
Yıllardır ASP.NET semineri dinlemişlerin affına sığınarak, bir kaç klişe görünen cümle kuracağım... ASP.NET, ASPnin en yeni hali olup, yeni bir sürümünden ziyade, sıfırdan ve başka bir mimari üstünde geliştirilmiş şeklidir. ASP.NETi, ASPden ayıran en önemli noktalardan biri, 3 katman mimarisine ve nesneye dayalı programlama desteğindeki gelişmişliktir. Elbette bunlar genel cümleler ancak, bu bir kaç sayfada, bu konuda fikir sahibi değilseniz "olayın temelini kavramaya" çalışacağız.
ADO.NETin de ADOnun yeni ve temelde farklı bir mimari üstünde geliştirilmiş hali olduğunu vurgulamaya gerek bile yok. Ancak burada, ADO.NET anlatmak yerine, ADO.NETin SQL Servere erişim için özel geliştirilmiş üç nesnesi, SqlDataReader, SqlConnection ve SqlCommand nesnelerinin yeraldığı örneğimizi inceleyeceğiz. Bu nesneler, yukarıda ele aldığımız ADO bileşenlerinden Connection, Command ve Recordset ile neredeyse aynı işlevleri yerine getirirler. Ancak elbette temellerinde çok farklı bir mimari yer almakta.
ADO
|
ADO.NET (SQL Server)
|
İşlevi
|
Connection
|
SqlConnection
|
Veritabanı ile uygulama arasında bir hat oluşturmak
|
Command
|
SqlCommand
|
Veritabanı ile etkileşecek sorguyu ve sorguyu oluşturan parametreleri tutmak ve yönetmek.
|
RecordSet
|
SqlDataReader
|
Veritabanından gelen verileri, program içerisinde yönetmeyi sağlamak. (Recordsetin işlevi bundan fazladır. Ancak bu karşılaştırma, recordsetin sadece veriyi okumak için kullanıldığını varsaymaktadır)
| Tablo 1: ADO ve ADO.NET nesnelerinden SQL Servere özgü olanlarının karşılıkları, bir program içerisinde ihtiyaç sırasında verilmiştir.
DİKKAT:
ADO.NET nesnelerinden, SqlDataReaderdeki herhangi bir satıra erişmek için, objSqlDataReader.Read()
denilerek, satırın açılması gerekir. Aksi halde, "satır yok" hatası ile karşılaşılır.
Sınıflar, Nesneler, Üç Katman Mimarisi
Üç Katman Mimarisi, özellikle nesneye dayalı programlama ile birlikte güç bulmuş, veritabanı programlamanın esas dinamiklerini oluşturan bir programlama eğilimi hatta trendidir. Bu nedenle, tam manasıyla bilinmesinde yarar vardır. Burada, Nesneye dayalı programlamada kullanılan teriminolojinin anlaşılır bir özetini yapmaya çalıştım. Geniş bilgi için, bu konuda bir kitap okumanızda yarar olabilir.
Nesne yönelimli programlamanın temelini Classlar oluşturur. Bir class, günlük anlamda bildiğimiz nesnenin kodlanarak tanımlamasıdır. Nesnelerle çalışma teorisinin temelinde, içeriğinin nasıl çalıştığını bilmeden onu kullanabilme mantığı yatar. Araba, DVD Player gibi... nasıl yaptıklarını bilmeyiz ama ne yaptıklarını biliriz.
• Bir class genel olarak şu yapıdan ibarettir(örnek için bölümün ilerleyen kısmında yer alan sınıflara bakabilirsiniz. )
- Methodlar, propertyler veya değişkenler(field) içerebilir( bunların her birine member denir)
- Method, prosedürel programlamada bildiğimiz fonksiyonun işlevini classlarda yerine getirir.
- Property prosedürel programlamada bildiğimiz değişkenin işlevini classlarda yerine getirir. Bu işlev için, değişken de kullanılabilir.
- Propertyler yazılabilir ve okunabilir olabilir. Sadece okunabilir veya sadece yazılabilir tanılanması methodlarla mümkündür. Ancak değişkenleri okunabilir yapmak için, Methodlar yerine, propery adı verilen yarı method yarı değişken yapı kullanılabilir.
- Methodlar ve değişkenler, sadece sınıf içerisinden erişilebilir veya bütün sınıflardan yahutta bütün assemlylerden erişilebilir olabilir veya erişilemez olarak kodlanabilir. Bunlar için, Public, Private, Internal, Protected, External... gibi deyimler(Erişim Tanımlayıcıları) kullanılır.
- Methodlar, aynı adda ama farklı girdi veya çıktı parametrede üst üste tanımlanabililir.(method overloading) Bu durumda, classın kullanımı aşamasında, çağrılış şekline en uygun method otomatik olarak algılanır ve devreye girer.
• Classlar yazıldıktan sonra, kütüphanelerde saklanırlar. MFC, .NET gibi belli bir geliştirme ortamı ile birlikte gelen kütüphanelere, temel kütüphane(base library-base class) denir. Bu ve kullanıcı tarafından geliştirilmiş kütüphaneler, isim uzayı (namespace) denilen nokta notasyonlu yapılarla düzenlenir. Namespace kavramı, fiziksel değil mantıksal bir kavramdır. Yani, farklı dokümanlarda birbiri ile aynı seviyede classlar olabilir.
- Düzenlenmiş Classlara erişim, isim uzayından sonra sınıf adı gelecek şekilde bir notasyon ile sağlanır.( System.Data.DataSet gibi)
- C# gibi dillerde, kütüphane sınıflarını, uygulamanın içerisindeymiş gibi doğrudan nesne adıyla çağırmak mümkündür. Ancak bunun için uygulamanın en başında, isim uzayları ve alt isim uzayları nokta notasyonu ile sınıf adına kadar veya belli bir seviyeye kadar belirtilebilir. Geri kalanlar, (sınıf adı veya isim uzayının tamamı belirtilmedi ise, belirtilmeyen kısmı) kod içerisinde belirtilerek, sınıflara erişilebilir.( using System.Data dendikten sonra daha herhangi bir yerde doğrudan DataSet denilerek, veya başta using System denilmişse, daha sonra Data.DataSet denilerek yahutta başta hiç bir şey denmeden, System.Data.DataSet denilerek erişmek mümkündür.)
• Classlar yeni classlar türetilirken şu şekilde kullanılarak kolaylıklar sağlarlar:
- Yeni bir classın çekirdeğini oluşturabilirler.(Implementation Inheritance)
- Bazı classlar miras almaya karşı korumaya alınabilir(Sealed Class)
- Bazı classlar miras alınmadan kullanılamaz tanımlanabilir(Abstract Class)
- Bazı classlar, miras alındıktan sonra, methodlarını geçersiz kılacak aynı adda yeni bir metod tanımlanabilir(method overriding)
- Kendisinden türeyecek classların yapıları hakkında söz sahibi olabilirler(Interface Inheritance)
• Classlar Bir Uygulama geliştirirken, şu şekilde kolaylıklar sağlarlar:
- Bazı class elemanları, static deyimi ile tanımlanmamışlardır ve nüshalandırma(instantiating) ile yeni class nüshası çıkartılarak, kullanılırlar. ASP biliyorsanız, ADODB.Connectionı düşünün. Hep nüshalandırarak kullanılır.
- Bazı methodlar ve propertiyler, değişkenler, çoğaltılamaz olabilir(static) Bu tür methodlar kulanılırken, classlar nüshalandırmaksızın, orijinal namespace ve sınıfın adı ile kullanılırlar. Response.Writei hatırlayın... hep aynı isim ile kullandık. Aşağıdaki örnekte, güvenlik işlemleri için geliştireceğimiz, MD5 ile özet alan Class da bu türdendir.
- Classlar, ebebeynleri ile aynı türdenmiş gibi davranabilirler. Böylece, temelde aynı classtan türetildikleri halde farklı türlerde olup aynı türmüş gibi davranan classlar elde edilebilir.(Polimorfizm)
Üç Katmanı Tasarlamak
Üç katman mimarisinin en alt katmanını, buraya kadar öğrendiğimiz tekniklerle geliştirdiğimiz, Veri katmanı oluşturur. Veri katmanı ile temasta bulunan, uygulamanın en alt katmanına iş katmanı denir ve prensip olarak classlardan oluşur. Classlar, meseleye çok iyi vakıf kişiler tarafından tasarlanabilirler.
Classları tasarlama için geliştirilmiş standart yollar var. Bunlardan en genel olanı UML(Unified Modeling Language)dir. Bu konuda yeni iseniz, nesneye dayalı bir dil ile kodlama işinin temellerini kavradıktan sonra UML ile de haşir neşir olmanız, yararlı olacaktır. Arkasından, genel olarak karşılaşılan sorunlara yaklaşım tarzları hakkında bilgi edinmek için Tasarım Desenleri (Design Pattern) öğrenmeniz, bu yoldaki son nokta olacaktır. Tasarım Deseni , sadece nesneye dayalı programlamaya uygulanmasa da, nesneye dayalı programlama için, bir çok tasarım desenini bir çok nesneye dayalı dilde bulmak mümkündür(C++, Java, C#).
Bütün bu detayları, size bırakıp projemizin genel olarak, üç katmana dağılımını inceleyelim:
Katman
|
İşlevi
|
Projemizde Yer Alacak Dosya-Bileşen Adları
|
Sunum
|
Kullanıcı ile etkişeşim, iş katmanında kodlanmış nesneleri nüshalandırıp kullanmak.
|
Login.aspx, Login.aspx.cs
|
İş
|
Sunum ve Veritabanı katmanları ile etkileşim.
İş kurallarının sağlanması
|
KullaniciVT.cs
Guvenlik.cs
|
Veri
|
Tablolar, Triggerlar, Stored Procedureler, Constraintler ve diğer veritabanı bileşenleri ile kurgulanmış veri mantığının sağlanması
|
tblKullanici, SP$yetkilendir
|
Tablo 2 : En üst katmanı oluşturan sunum katmanının görevi, iş katmanı ile kullanıcıyı etkileştirmektir. Sunum katmanı doğrudan veritabanına erişmez! Bu işlemler için, iş katmanında geliştirilmiş Classları nüshalandırarak kullanabilir.
Veri Katmanını Kurgulamak
Örneğimizi, üç katman mimarisi olarak ele alalım. Öncelikle, veri katmanını kurgulayacağız. Bu katmanda, tblKullanici adında bir kullanıcı kayıtlarının yer aldığı tablo var. Bu tabloya erişip verilerin doğruluğunu onaylayan, SP$yetkilendir adında stored procedure ü aşağıdaki şekilde kodladığımızı varsayalım, bu nedenle tablo ve veritabanının geri kalan şemasını bir tarafa bırakabiliriz. Stored Procedurelerin üç katmanlı uygulamalar tasarlamadaki, en büyük avantajlarından biri de budur.
CREATE PROC SP$yetkilendir(
@kullaniciAd VARCHAR(50),
@sifre VARCHAR(50),
@yetkiSeviye INT=NULL OUT ,
@sonGirisTarih VARCHAR(12) =NULL OUT,
@isim VARCHAR(30)=NULL OUT
)
AS
DECLARE @kullaniciKod INT
IF @kullaniciAd IS NULL OR @sifre IS NULL
RETURN 0
SELECT @kullaniciKod=kullaniciKod,
@yetkiSeviye=yetkiSeviye,
@sonGirisTarih=CONVERT(VARCHAR(12),sonGirisTarih,104),
@isim=isim + + soyad
FROM tblKullanici
WHERE kullaniciAd=@kullaniciAd AND @sifre=@sifre
IF @kullaniciKod IS NOT NULL
BEGIN
-- böyle bir kullanıcı var.
RETURN @kullaniciKod
-- Son giriş Tarihini ve giriş sayısını değiştirelim
UPDATE tblKullanici
SET sonGirisTarih=GETDATE(),girisSayisi=girisSayisi+1
WHERE kullaniciAd=@kullaniciAd AND @sifre=@sifre
END
ELSE
RETURN 0
GO |
İş Katmanını Tasarlamak
Bir sonraki katman olan iş katmanını tasarlamaya geçelim. Bu iş için, nesneye dayalı programlamaya tam destek sağlayan, Managed C# dilini kullanacağız. Managed ve Unmanaged kavramları kafanızı karıştırabilir. Aralarında ufak bir fark vardır: Managed ortamda, sistemden hafıza gibi kaynak alma ve sisteme bu kaynağı, işi bittiğinde iade etme işini, çalıştırma ortamı yerine getirir. JVM ve .NET Framework bu türden ortamlardır. Ama ortam, her zaman böyle olmayabilir. Şayet işletim sistemi ile kaynak alış-verişini programcının kendisi yürütüyorsa, (ki bu durumda programcıya çok fazla iş düşer ve sistemde daha fazla hata ihtimali vardır!) bu türden çalıştırma ortamına da Unmanaged ortam denir.
C# bir dil olarak her iki ortamı da destekler. Ancak .NET ortamı, C#ın bütün meziyetlerini gösterebileceği bir ortam değildir. Buna rağmen, biz .NET ortamında çalışacağız. Veritabanına erişip kullanıcı ile ilgili işlemleri yerine getirecek bir sınıfa ihtiyacımız var. Bu sınıfa KullaniciVT adını verelim. Class adlarının ilk harfi büyük harfle başlatılır. Bu bir zorunluluk değildir ama töre olmuş bir kodlama tarzıdır. Şimdi ilk sınıfımızı kodlayalım:
Bu sınıfın amacı, Webden gelen verileri her seferinde özetlemek (Digest)tir. Bir üyemiz ilk kaydolduğunda, seçtiği şifresi veritabanımızda saklanmaz. Bunun yerine, özeti saklanır. Daha sonra, yetkilendirmek için geldiğinde de şifresinin özeti alınır. Böylelikle, her seferinde gelen veririn daha önceki veri olup olmadığı bilinir, ama en önemli tarafı, ne olduğu asla bilinemez. Çünkü özet alma ile şifreleme yapan, SHA, MD5 gibi algoritamalar, tek yönlü veri dönüşümünü esas alan, ters yönde bir dönüşüme asla müsade etmeyen algoritmalardır.
///Guvenlik.cs
using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace Verivizyon.Bilesenler
{
public class Guvenlik
{
public static string OzetCek(string gercekDuzMetin)
{
Byte[] gercekByteMetin = new
UnicodeEncoding().GetBytes(gercekDuzMetin);
Byte[] ozetByteMetin = ((HashAlgorithm)
CryptoConfig.CreateFromName("MD5")).ComputeHash(gercekByteMetin);
return BitConverter.ToString(ozetByteMetin);
}
}
} |
İPUCU:
C#ta fonksiyon yoktur. Bunun yerine, classların methodlarını kullanacağız. Ancak bir methodu, gerçek manada sabit bir fonksiyon gibi her yerde nüshalandırmadan kullanmak istiyorsanız, static deyimi ile tanımlayabilirsiniz.
Takip eden sınıfları, aşağıdaki gibi kodlayalım
///dosya:KullaniciVT.cs
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
namespace Verivizyon
{
//KullaniciVT, kullanicilarla veritabani
// arasinda iliskiyi kuran,
//is mantigi saglayicisidir.
public class KullaniciDetay
{
public string kullaniciAd;
/*Kullanicida bulunan ozellikler
*..
* */
}
public class YetkilendirmeBilgi
{
/*
* Yetkilendirilen kisiye ait, kullanici kodu, isim, soyad
* son giris tarihi gibi bilgileri encapsulate etmede kullanilir.
* */
public string kullaniciKod;
public string isim;
public string sonGirisTarih;
}
public class KullaniciVT
{
public KullaniciDetay KullanicininBilgileri(int kullaniciKod)
{
/* kullanici bilgilerini veritabanindan cek
* kullaniciDetay classindan bir nusha al
* vertabanindan gelen verileri bu nushaya yukle
* neticeyi, methodu cagirana dondur
* */
KullaniciDetay KullaniciBilgileri= new KullaniciDetay();
return KullaniciBilgileri;
}
public YetkilendirmeBilgi KullaniciYetkilendir(string kullaniciAd,
string sifre)
{
// Bir adet connection ve bir adet command nesnesi olusturalim
SqlConnection Conn = new
SqlConnection(ConfigurationSettings.AppSettings["DSN"]);
// DSN parametresi, web.config dosyasinda,
// sekildeki gibi tutulmaktadir.
SqlCommand Cmd = new SqlCommand("SP$yetkilendir", Conn);
Cmd.CommandType = System.Data.CommandType.StoredProcedure;
Cmd.Connection = Conn;
Cmd.CommandType = System.Data.CommandType.StoredProcedure;
Cmd.Connection = Conn;
// Parameter : @KullaniciKod
Cmd.Parameters.Add(new
System.Data.SqlClient.SqlParameter("@KullaniciKod",
System.Data.SqlDbType.Int, 4));
Cmd.Parameters["@KullaniciKod"].Direction =
System.Data.ParameterDirection.ReturnValue;
// Parameter : @kullaniciAd
Cmd.Parameters.Add(new
System.Data.SqlClient.SqlParameter("@kullaniciAd",
System.Data.SqlDbType.VarChar, 50));
Cmd.Parameters["@kullaniciAd"].Direction =
System.Data.ParameterDirection.Input;
Cmd.Parameters["@kullaniciAd"].Value = kullaniciAd;
// Parameter : @sifre
Cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@sifre",
System.Data.SqlDbType.VarChar, 50));
Cmd.Parameters["@sifre"].Direction =
System.Data.ParameterDirection.Input;
Cmd.Parameters["@sifre"].Value = sifre;
// Parameter : @yetkiSeviye
Cmd.Parameters.Add(new
System.Data.SqlClient.SqlParameter("@yetkiSeviye",
System.Data.SqlDbType.Int, 4));
Cmd.Parameters["@yetkiSeviye"].Direction =
System.Data.ParameterDirection.Output;
// Parameter : @sonGirisTarih
Cmd.Parameters.Add(new
System.Data.SqlClient.SqlParameter("@sonGirisTarih",
System.Data.SqlDbType.VarChar, 12));
Cmd.Parameters["@sonGirisTarih"].Direction =
System.Data.ParameterDirection.Output;
// Parameter : @isim
Cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@isim",
System.Data.SqlDbType.VarChar, 30));
Cmd.Parameters["@isim"].Direction =
System.Data.ParameterDirection.Output;
Conn.Open();
Cmd.ExecuteNonQuery();
string KullaniciKod=
Cmd.Parameters["@KullaniciKod"].Value.ToString();
if (KullaniciKod=="0")
{
Conn.Close();
return null;
}
else
{
YetkilendirmeBilgi YetkiBilgileri= new YetkilendirmeBilgi();
YetkiBilgileri.kullaniciKod =
Cmd.Parameters["@KullaniciKod"].Value.ToString();
YetkiBilgileri.isim=Cmd.Parameters["@isim"].Value.ToString();
YetkiBilgileri.sonGirisTarih =
Cmd.Parameters["@sonGirisTarih"].Value.ToString();
Conn.Close();
return YetkiBilgileri;
}
}
public string KullaniciEkle(KullaniciDetay yeniKullanici)
{
/* Kullanici bilgilerini yeniKullanici nüshasindan al
* Command nesnesine aktar
* ifadeyi calistir.
* neticesini cagrildigi yere dondur.
* */
return null;
}
}
} |
KullaniciDetay ve YetkilendirmeBilgi sınıfları, veri kılıflaması (encapsulation) için kulanılmaktadır. Amaç, verilerin belli bir formatta bütün olarak aktarılabilmesini sağlamaktır. Bu amaç için, C#ta struct tipi değişkenler de kullanılabilirdi ancak, biz classlarla bu işi gerçekleştirdik.
KullaniciVT sınıfının birçok metodu yeralmakta. Çünkü, ele aldığımız örnekte, bütün işlemler bu sınıfa düşmekte. Ancak sınıfın sadece örnekte gerekli olan kısımlarını gerçekledik, diğer taraflarını basitliği korumak için gerçeklemedik.
Bu metodlardan, KullaniciYetkilendir , dışarıdan aldığı iki parametreyi kullanarak, SP$yetkilendir stored procedureüne erişip veri katmanı ile bilgileri kontrol edebilmektedir. Sonuçta, yetkilendirme işlemi olursa, YetkilendirmeBilgi sınıfından bir nüsha alınmakta ve bu nüshaya doldurulan veriler(encapsulation) çağrıldığı yere, gönderilmektedir. Yetkilendirme olmazsa, null değeri gönderilmektedir. Peki bu sınıf veritabanına hangi bağltantı ifadesini kullanarak erişmektedir? Öncelikle, web.config dosyasına bir göz atalım:
Şekild 1: Veritabanı erişimi ile ilgili ifadelerin, XML formatında uygulamanın konfigürasyon bilgilerini tutan web.config dosyasına eklenmesi
web.config de yer alan bu bilgiler, aşağıdaki şekilde erişilip kullanılmaktadır.
SqlConnection Conn = new SqlConnection(ConfigurationSettings.AppSettings["DSN"]);
|
Ancak, bu ifadeleri kullanabilmek için, ilgili isimuzaylarını(namespace) yüklemeniz gerekir. Bu işten sorumlu içerik, using System.Configuration; deyimi ile, ilgili temel sınıfların (base class) bulunduğu kütüphaneyi projemizin parçası haline getirdik.
Büyük uygulamalarda, iş katmanı, içerisinde yer verilen bütün sınıflar ve methodlarla, namespace yardımıyla da düzenlenerek, kendi başına bir proje olarak ele alınır ve bir dll haline getirilerek kullanılır. Bütün iş katmanını içine alan bu yapıya, Application Framework ( Uygulama Omurgası ) adı verilir.
Sunum Katmanını Tasarlamak
Bu sınıfları gerçekledikten sonra, iş katmanındaki işlemlerimizi bitirmiş olduk. Sıra geldi, sunum katmanına. Sunum katmanında, bu iki dosyada yer alan sınıfları türetip kullanacağız. Bu türetme işleminin, ASP için Connection nesnesini kullanmaktan bir farkı bulunmamakta.
Öncelikle, bir Visual Studio.NET 2003-Web projesi başlatalım. Ve ardından, bir önceki aşamada oluşturduğumuz iki dosyayı bu proje ile ilişkilendirelim. (uygulama frameworkü kullanmak fikirini, bir kenara not edip kendiniz detaylandırabilirsiniz.)
Ardından, kullanıcıdan verileri alabilecek ve verilerinin doğru olup olmadığını ona aktarabilecek bir aspx dosyasını aşağıdaki şekilde tasarlayalım.
Şekil 2: Yeni bir Form başlatıp adını, login.aspx olarak değiştirelim ve bir Label, iki Textbox ve bir adet de Button nesnesi ekleyelim.
<%@ Page language="c#" Codebehind="login.aspx.cs" AutoEventWireup="false" Inherits="Verivizyon.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<!--dosya: login.aspx-->
<HTML>
<HEAD>
<title>Üye Giriş Sayfası</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:Label id="LblSonuc" runat="server">
</asp:Label><BR>
>Kullanici Adiniz<asp:TextBox id="TxtKullanici" runat="server">
</asp:TextBox><BR>
Sifreniz <asp:TextBox id="TxtSifre" runat="server" TextMode="Password"></asp:TextBox>
<asp:Button id="BtnSubmit" runat="server" Text="Giris">
</asp:Button>
</form>
</body>
</HTML> |
Codebehind dosyası, Visual Studio tarafından otomatik oluşturulmakta. Bizim tüm yapmamız gereken, butonu çift tıklamak ve içerisine şu kodları eklemek:
// yetkilendirmeyi yapacak sinifi olusturalim
Verivizyon.KullaniciVT kullanici = new KullaniciVT();
//yetkilendirme sonucunu encapsulate edecek sinifi
//olusturalim
Verivizyon.YetkilendirmeBilgi yetkilendirmeBilgi= new YetkilendirmeBilgi();
//YetkilendirmeBilgi.KullaniciYetkilendir() metodunu
// nasıl çağırdığımıza ve
// Şifrenin nasıl özetinin çekildiğine dikkat edin...
yetkilendirmeBilgi = kullanici.KullaniciYetkilendir(TxtKullanici.Text, Verivizyon.Bilesenler.Guvenlik.OzetCek(TxtSifre.Text));
if(yetkilendirmeBilgi != null){
LblSonuc.Text = "Merhaba " +
yetkilendirmeBilgi.isim +
" sitemize en son " +
yetkilendirmeBilgi.sonGirisTarih +
" tarihinde giris yaptiniz" ;
} |
Görüldüğü üzere, veritabanına doğrudan bir erişim yer almamaktadır. Sadece, bir alt katmanda oluşturulan sınıflar nüshalandırıldı(instantaiting) ve bu nesneler kullanıldı.
Uygulama ilk başladığında, ilgili mesajı kullanıcılarımıza göstermek için, şu kodu da ekleyebiliriz:
private void Page_Load(object sender, System.EventArgs e)
{
if(!isPostBack)
LblSonuc.Text = "Lütfen Kullanici adi ve sifrenizi giriniz.";
} |
Şekil 3: Projenin çalışan hali
Projenin tamamını, kitap yayınlandıktan sonra, destek sayfalarından indirebilirsiniz.
Neler öğrendik
- Nesneye dayalı programlamanın temel teriminolojisi
- Üç katman mimarisini kurgulamak.
- Veri katmanında bir stored procedure tanımlayarak verilere programsal bir arayüzden erişim sağlamak.(Data Katmanı)
- Uygulamanın çatısını oluşturacak nesneleri planlayıp Classlar halinde hiyerarşik olarak bir araya getirerek, uygulamanın omurgasını inşa etmek.(İş Katmanı)
- Uygulamanın inşa edilmiş omurgasının üstüne, kullanıcı ile etkileşimi sağlayacak, daha çok görsel ve etkileşim ile ilgili ama ufak tefek programsal ifadelerin de yer aldığı bir arayüz ile uygulamayı tamamlamak(Sunum).
Yaşar Gözüdeli
Makale:
Nesneye Dayali Programlama, 3 Katman Mimarisi ve ASP.NET ASP.NET Yaşar Gözüdeli
|