2. Spring / NHibernate Entegrasyonu
Spring çerçevesi, NHibernate çerçevesi ile çalışmak için yardımcı sınıflar sunar. Bu sınıfların kullanılması, bir SGBD'teki verilere erişim kodunun yazılmasını kolaylaştırır. Aşağıdaki çok katmanlı mimariyi ele alalım:
![]() |
Bundan sonra, işlevsel bir çözümün kodunu inceleyerek [Spring / NHibernate] ile bir [dao] katmanı oluşturacağız. [Spring / Nhibernate] çerçevesinin tüm yapılandırma veya kullanım olanaklarını ele almaya çalışmayacağız. Okuyucu, Spring.NET [Spring.NET | Homepage ] (Aralık 2011) belgelerinden yararlanarak önerilen çözümü kendi sorunlarına uyarlayabilir.
2.1. [dao] veri erişim katmanı
![]() |
Veritabanı, 1.2. paragrafta daha önce tanıtılan MySQL [dbpam_nhibernate] veritabanıdır. [dao] katmanı, aşağıdaki C# arayüzünü uygular:
using Pam.Dao.Entites;
namespace Pam.Dao.Service {
public interface IPamDao {
// tüm çalışan kimliklerinin listesi
Employe[] GetAllIdentitesEmployes();
// belirli bir çalışanın ödenekleri
Employe GetEmploye(string ss);
// tüm primlerin listesi
Cotisations GetCotisations();
}
}
2.1.1. [dao] katmanının Visual Studio C# projesi
[dao] katmanının Visual Studio projesi şöyledir:
![]() |
- [1]'te, projenin tamamı
- [pam] klasörü, projenin sınıflarını ve varlık yapılandırmasını içerir NHibernate
- [App.config] ve [Dao.xml] dosyaları Spring çerçevesini yapılandırır / NHibernate. Bu iki dosyanın içeriğini açıklamamız gerekecek.
- [2] dosyasında, projenin çeşitli sınıfları bulunur
- [entites] klasöründe, önceki projede incelenen NHibernate varlıklarını buluyoruz (bkz. sayfa 14)
- [service] klasöründe, [IPamDao] arayüzünü ve Spring çerçeve ile gerçekleştirilmiş halini (NHibernate, [PamDaoSpringNHibernate]) buluyoruz.
- [tests] klasörü, [IPamDao] arayüzünün testlerini içerir.
- [3] dosyasında proje referansları bulunur. Spring / NHibernate entegrasyonu için yeni DLL ve [4] dosyaları gereklidir.
Projenin [3] referanslarında şu DLL'ler bulunur:
- NHibernate: ORM ve NHibernate için
- MySql.Data: ADO.NET sürücüsü, SGBD ve MySQL için 5
- Spring.Core: Katmanların entegrasyonunu sağlayan Spring çerçeve için
- log4net: bir günlük kütüphanesi
- nunit.framework: birim test kütüphanesi
- Spring.Aop, Spring.Data ve Spring.Data.NHibernate32: Spring / NHibernate desteğini sağlar.
Tüm bu DLL öğelerinin "Yerel Kopya" özelliğinin True olarak ayarlanmasını sağlayacağız.
2.1.2. C# projesinin yapılandırması
Proje şu şekilde yapılandırılmıştır:
![]() |
- [1]'te, projenin derleme adı [pam-dao-spring-nhibernate]'tir. Bu ad, projenin çeşitli yapılandırma dosyalarında geçerlidir.
2.1.3. [dao] katmanındaki varlıklar
![]() |
[dao] katmanı için gerekli varlıklar (nesneler), projenin [entites] [1] klasöründe toplanmıştır. Bu varlıklar, önceki projeninkilerle aynıdır (bkz. paragraf 1.3.2); tek fark, NHibernate yapılandırma dosyalarında yer almalarıdır. Örneğin, [Employe.hbm.xml] dosyasını ele alalım:
- [2] dosyasında, dosya projenin derlemesine dahil edilecek şekilde yapılandırılmıştır
İçeriği şöyledir:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Pam.Dao.Entites" assembly="pam-dao-spring-nhibernate">
<class name="Employe" table="EMPLOYES">
<id name="Id" column="ID">
<generator class="native" />
</id>
<version name="Version" column="VERSION"/>
<property name="SS" column="SS" length="15" not-null="true" unique="true"/>
<property name="Nom" column="NOM" length="30" not-null="true"/>
<property name="Prenom" column="PRENOM" length="20" not-null="true"/>
<property name="Adresse" column="ADRESSE" length="50" not-null="true" />
<property name="Ville" column="VILLE" length="30" not-null="true"/>
<property name="CodePostal" column="CP" length="5" not-null="true"/>
<many-to-one name="Indemnites" column="INDEMNITE_ID" cascade="all" lazy="false"/>
</class>
</hibernate-mapping>
- 3. satır: assembly özniteliği, [Employe.hbm.xml] dosyasının [pam-dao-spring-nhibernate] derlemesinde bulunacağını belirtir
Ayrıca, [entites] klasöründe, proje tarafından kullanılan bir istisna sınıfı buluyoruz:
using System;
namespace Pam.Dao.Entites {
public class PamException : Exception {
// hata kodu
public int Code { get; set; }
// üreticiler
public PamException() {
}
public PamException(int Code)
: base() {
this.Code = Code;
}
public PamException(string message, int Code)
: base(message) {
this.Code = Code;
}
public PamException(string message, Exception ex, int Code)
: base(message, ex) {
this.Code = Code;
}
}
}
[PamException] sınıfı, bir hata kodu eklemek amacıyla (7. satır) [Exception] sınıfından türetilmiştir (4. satır).
2.1.4. Spring Yapılandırması / NHibernate
Visual C# projesine geri dönelim:
![]() |
- [1] dosyasında, [App.config] ve [Dao.xml] dosyaları Spring entegrasyonunu yapılandırır / NHibernate
2.1.4.1. [App.config] dosyası
[App.config] dosyası şöyledir:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- yapılandırma bölümleri -->
<configSections>
<sectionGroup name="spring">
<section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<!-- Spring yapılandırması -->
<spring>
<parsers>
<parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" />
</parsers>
<context>
<resource uri="Dao.xml" />
</context>
</spring>
<!-- Bu bölüm log4net yapılandırma ayarlarını içerir -->
<!-- NOTE IMPORTANTE: Günlükler varsayılan olarak etkin değildir. Program aracılığıyla etkinleştirilmeleri gerekir
avec l'instruction log4net.Config.XmlConfigurator.Configure();
! -->
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %logger - %message%newline" />
</layout>
</appender>
<!-- Varsayılan günlük kaydı düzeyini DEBUG olarak ayarlayın -->
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
</root>
<!-- Spring için günlük kaydı ayarlayın. Spring'deki günlük kaydedici adları ad alanına karşılık gelir -->
<logger name="Spring">
<level value="INFO" />
</logger>
<logger name="Spring.Data">
<level value="DEBUG" />
</logger>
<logger name="NHibernate">
<level value="DEBUG" />
</logger>
</log4net>
</configuration>
Yukarıdaki [App.config] dosyası Spring'i (5-9. satırlar, 15-22. satırlar) ve log4net'i (10. satır, 28-53. satırlar) yapılandırır, ancak NHibernate'i yapılandırmaz. Spring nesneleri [App.config] dosyasında değil, [Dao.xml] dosyasında (20. satır) yapılandırılmıştır. Dolayısıyla, belirli Spring nesnelerini tanımlamaktan ibaret olan Spring yapılandırması / NHibernate bu dosyada bulunacaktır.
2.1.4.2. [Dao.xml] dosyası
Spring tarafından yönetilen nesneleri bir araya getiren [Dao.xml] dosyası şöyledir:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:db="http://www.springframework.net/database">
<!-- Ana uygulama bağlamı yapılandırma dosyası tarafından referans alınır -->
<description>
Application Spring / NHibernate
</description>
<!-- Veritabanı ve NHibernate Yapılandırması -->
<db:provider id="DbProvider"
provider="MySql.Data.MySqlClient"
connectionString="Server=localhost;Database=dbpam_nhibernate;Uid=root;Pwd=;"/>
<object id="NHibernateSessionFactory" type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>pam-dao-spring-nhibernate</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="dialect" value="NHibernate.Dialect.MySQL5Dialect"/>
<entry key="hibernate.show_sql" value="false"/>
</dictionary>
</property>
<property name="ExposeTransactionAwareSessionFactory" value="true" />
</object>
<!-- işlem yöneticisi -->
<object id="transactionManager"
type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32">
<property name="DbProvider" ref="DbProvider"/>
<property name="SessionFactory" ref="NHibernateSessionFactory"/>
</object>
<!-- Hibernate Şablonu -->
<object id="HibernateTemplate" type="Spring.Data.NHibernate.Generic.HibernateTemplate">
<property name="SessionFactory" ref="NHibernateSessionFactory" />
<property name="TemplateFlushMode" value="Auto" />
<property name="CacheQueries" value="true" />
</object>
<!-- Veri Erişim Nesneleri -->
<object id="pamdao" type="Pam.Dao.Service.PamDaoSpringNHibernate, pam-dao-spring-nhibernate" init-method="init" destroy-method="destroy">
<property name="HibernateTemplate" ref="HibernateTemplate"/>
</object>
</objects>
- 11-13. satırlar, [dbpam_nhibernate] veritabanına bağlantıyı yapılandırır. Burada şunlar bulunur:
- Bağlantı için gerekli olan ADO.NET sağlayıcısı; burada SGBD MySQL sağlayıcısı kullanılmaktadır. Bu, proje referanslarında DLL ve [Mysql.Data]'in bulunması gerektiği anlamına gelir.
- veritabanına bağlantı dizesi (sunucu, veritabanı adı, bağlantı sahibi, şifresi)
- 15-29. satırlar, SessionFactory'i NHibernate'ten yapılandırır; bu nesne, NHibernate oturumlarını elde etmek için kullanılır. Veritabanındaki tüm işlemlerin bir NHibernate oturumu içinde gerçekleştirildiğini hatırlatırız. 15. satırda, SessionFactory'in, DLL ve Spring.Data.NHibernate32 içinde bulunan Spring sınıfı Spring.Data.NHibernate.LocalSessionFactoryObject tarafından uygulandığı görülebilir.
- 16. satır: DbProvider özelliği, veritabanı bağlantısının parametrelerini (ADO.NET sağlayıcısı ve bağlantı dizesi) belirler. Burada bu özellik, daha önce 11-13. satırlarda tanımlanan DbProvider nesnesine başvurur.
- 17-20. satırlar: [*.hbm.xml] dosyalarını içeren derleme listesini belirler; bu dosyalar, NHibernate tarafından yönetilen varlıkların yapılandırılmasını sağlar. 19. satır, bu dosyaların proje derlemesinde bulunacağını belirtir. Bu adın C# projesinin özelliklerinde bulunduğunu hatırlatırız. Ayrıca, tüm [*.hbm.xml] dosyalarının proje derlemesine dahil edilmek üzere yapılandırıldığını da hatırlatırız.
- 22-27. satırlar: NHibernate'e özgü özellikler.
- 24. satır: Kullanılacak SQL lehçesi, MySQL'inkiyle aynı olacaktır
- 25. satır: NHibernate tarafından üretilen SQL, konsol günlüklerinde görünmeyecektir. Bu özelliği true olarak ayarlamak, NHibernate tarafından gönderilen SQL komutlarını görmenizi sağlar. Bu, örneğin bir uygulamanın veritabanına erişirken neden yavaşladığını anlamanıza yardımcı olabilir.
- 28. satır: ExposeTransactionAwareSessionFactory'ten true'e ayarlanan özellik, Spring'in C# kodunda bulunan işlem yönetimi anotasyonlarını yönetmesini sağlayacaktır. [dao] katmanını uygulayan sınıfı yazarken bu konuya tekrar değineceğiz.
- 32-36. satırlar işlem yöneticisini tanımlar. Burada da bu yönetici, DLL ve Spring.Data.NHibernate32 sınıflarından oluşan bir Spring sınıfıdır. Bu yönetici, veritabanına bağlantı parametrelerini (satır 34) ve SessionFactory ile NHibernate sınıflarını (satır 35) bilmelidir.
- 39-43. satırlar, yine bir Spring sınıfı olan HibernateTemplate sınıfının özelliklerini tanımlar. Bu sınıf, [dao] katmanını uygulayan sınıfta yardımcı sınıf olarak kullanılacaktır. NHibernate nesneleriyle etkileşimi kolaylaştırır. Bu sınıfın başlatılması gereken bazı özellikleri vardır:
- 40. satır: NHibernate sınıfının SessionFactory özelliği
- 41. satır: TemplateFlushMode özelliği, NHibernate kalıcılık bağlamının veritabanıyla senkronizasyon modunu belirler. Auto modu, senkronizasyonun şu şekilde gerçekleşmesini sağlar:
- bir işlemin sonunda
- bir select işlemi öncesinde
- 42. satır: HQL (Hibernate Query Language) sorguları önbelleğe alınacaktır. Bu, performans artışı sağlayabilir.
- 46-48. satırlar, [dao] katmanının uygulama sınıfını tanımlar
- 46. satır: [dao] katmanı, DLL ve [pam-dao-spring-nhibernate] sınıflarından oluşan [PamdaoSpringNHibernate] sınıfı tarafından uygulanacaktır. Sınıfın örneği oluşturulduktan sonra, sınıfın init yöntemi hemen çalıştırılacaktır. Spring konteyneri kapatıldığında, sınıfın destroy yöntemi çalıştırılacaktır.
- 47. satır: [PamDaoSpringNHibernate] sınıfı, 39. satırdaki HibernateTemplate özelliğiyle başlatılacak olan HibernateTemplate özelliğine sahip olacaktır.
2.1.5. [dao] katmanının uygulaması
2.1.5.1. Uygulama sınıfının iskeleti
[IPamDao] arayüzü şu şekildedir:
using Pam.Dao.Entites;
namespace Pam.Dao.Service {
public interface IPamDao {
// tüm çalışan kimliklerinin listesi
Employe[] GetAllIdentitesEmployes();
// belirli bir çalışan ve ödenekleri
Employe GetEmploye(string ss);
// Tüm primlerin listesi
Cotisations GetCotisations();
}
}
- 1. satır: [dao] katmanındaki varlıkların ad alanı içe aktarılır.
- 3. satır: [dao] katmanı, [Pam.Dao.Service] ad alanında yer alır. [Pam.Dao.Entites] ad alanındaki öğeler birden fazla kopya halinde oluşturulabilir. [Pam.Dao.Service] ad alanındaki öğeler ise tek bir kopya halinde (singleton) oluşturulur. Ad alanlarının isimlerinin bu şekilde seçilmesinin nedeni budur.
- 4. satır: Arayüzün adı [IPamDao]'tir. Üç yöntem tanımlar:
- 6. satırda, [GetAllIdentitesEmployes], çocuk bakıcılarının listesini basitleştirilmiş bir biçimde (soyadı, adı, SS) temsil eden [Employe] türünde bir nesne dizisi döndürür.
- 8. satırda, [GetEmploye], [Employe] nesnesini döndürür: yönteme parametre olarak verilen sosyal güvenlik numarasına sahip çalışan ve endeksine bağlı ödenekler.
- 10. satırda, [GetCotisations], brüt maaştan kesilecek çeşitli sosyal güvenlik prim oranlarını içeren [Cotisations] nesnesini döndürür.
Spring / NHibernate desteği ile bu arayüzün uygulama sınıfının iskeleti şu şekilde olabilir:
using System;
using System.Collections;
using System.Collections.Generic;
using Pam.Dao.Entites;
using Spring.Data.NHibernate.Generic.Support;
using Spring.Transaction.Interceptor;
namespace Pam.Dao.Service {
public class PamDaoSpringNHibernate : HibernateDaoSupport, IPamDao {
// özel alanlar
private Cotisations cotisations;
private Employe[] employes;
// başlatma
[Transaction(ReadOnly = true)]
public void init() {
...
}
// nesnenin silinmesi
public void destroy() {
if (HibernateTemplate.SessionFactory != null) {
HibernateTemplate.SessionFactory.Close();
}
}
// tüm çalışan kimliklerinin listesi
public Employe[] GetAllIdentitesEmployes() {
return employes;
}
// belirli bir çalışan ve ödenekleri
[Transaction(ReadOnly = true)]
public Employe GetEmploye(string ss) {
....
}
// prim listesi
public Cotisations GetCotisations() {
return cotisations;
}
}
}
- 9. satır: [PamDaoSpringNHibernate] sınıfı, [dao] [IPamDao] katmanının arayüzünü başarıyla uygular. Ayrıca Spring [HibernateDaoSupport] sınıfından türetilmiştir. Bu sınıfın, yapılan Spring yapılandırmasıyla (aşağıdaki 2. satır) başlatılan bir [HibernateTemplate] özelliği vardır:
<object id="pamdao" type="Pam.Dao.Service.PamDaoSpringNHibernate, pam-dao-spring-nhibernate" init-method="init" destroy-method="destroy">
<property name="HibernateTemplate" ref="HibernateTemplate"/>
</object>
- Yukarıdaki 1. satırda, [pamdao] nesnesinin tanımında, [PamDaoSpringNHibernate] sınıfının init ve destroy yöntemlerinin belirli zamanlarda yürütülmesi gerektiği belirtilmektedir. Bu iki yöntem, sınıfın 16. ve 21. satırlarında yer almaktadır.
- 15. ve 34. satırlar: Anotasyonlar, anotasyon uygulanan yöntemin bir işlem içinde çalıştırılmasını sağlar. ReadOnly=true özniteliği, işlemin salt okunur olduğunu belirtir. İşlem içinde yürütülen yöntem bir istisna oluşturabilir. Bu durumda, Spring tarafından işlemin otomatik olarak Rollback ile sonlandırılması gerçekleştirilir. Bu anotasyon, yöntem içinde bir işlemi yönetme ihtiyacını ortadan kaldırır.
- 16. satır: init yöntemi, sınıfın örneklendirilmesinden hemen sonra Spring tarafından yürütülür. Bu yöntemin amacının, 11. ve 12. satırlardaki özel alanları başlatmak olduğunu göreceğiz. Yöntem, bir işlem içinde gerçekleştirilecektir (15. satır).
- [IPamDao] arayüzünün yöntemleri 28., 35. ve 40. satırlarda uygulanmaktadır.
- 28-30. satırlar: [GetAllIdentitesEmployes] yöntemi, init yöntemi tarafından başlatılan 12. satırdaki özniteliği döndürmekle yetinir.
- 40-42. satırlar: [GetCotisations] yöntemi, init yöntemi tarafından başlatılan 11. satırdaki özniteliği döndürmekle yetinir.
2.1.5.2. HibernateTemplate sınıfının kullanışlı yöntemleri
HibernateTemplate sınıfının aşağıdaki yöntemlerini kullanacağız:
HQL sorgusunu yürütür ve T türünde bir nesne listesi döndürür | |
? ile parametreleştirilmiş bir HQL sorgusunu yürütür. Bu parametrelerin değerleri nesne dizisi tarafından sağlanır. | |
T türündeki tüm varlıklarını döndürür |
Varlıkları bulmaya, kaydetmeye, güncellemeye ve silmeye olanak tanıyan, kullanma fırsatımız olmayacak başka yararlı yöntemler de mevcuttur:
NHibernate oturumuna, birincil anahtarı id olan T türündeki varlığı ekler. | |
entité nesnesini, birincil anahtarı (UPDATE) olup olmadığına göre ya ekler (INSERT) ya da günceller (UPDATE) (INSERT). Birincil anahtarın olmaması, varlığın yapılandırma dosyasındaki unsaved-values özniteliği ile yapılandırılabilir. SaveOrUpdate işlemi sonrasında, entité nesnesi NHibernate oturumunda bulunur. | |
, entité nesnesini NHibernate oturumundan siler. |
2.1.5.3. init yönteminin uygulanması
[PamDaoSpringNHibernate] sınıfının init yöntemi, yapılandırma gereği Spring tarafından sınıfın örneklendirilmesinden sonra yürütülen yöntemdir. Bu yöntemin amacı, çalışanların basitleştirilmiş kimlik bilgilerini (soyadı, adı, SS) ve katkı payı oranlarını yerel önbelleğe kaydetmektir. Kod şu şekilde olabilir:
[Transaction(ReadOnly = true)]
public void init() {
try {
// basitleştirilmiş çalışan listesini alıyoruz
IList<object[]> lignes = HibernateTemplate.Find<object[]>("select e.SS,e.Nom,e.Prenom from Employe e");
// bir tabloya aktarılır
employes = new Employe[lignes.Count];
int i = 0;
foreach (object[] ligne in lignes) {
employes[i] = new Employe() { SS = ligne[0].ToString(), Nom = ligne[1].ToString(), Prenom = ligne[2].ToString() };
i++;
}
// prim oranlarını bir nesneye yerleştirilir
cotisations = (HibernateTemplate.LoadAll<Cotisations>())[0];
} catch (Exception ex) {
// istisnayı dönüştürme
throw new PamException(string.Format("Erreur d'accès à la BD : [{0}]", ex.ToString()), 43);
}
}
- 5. satır: Bir HQL sorgusu yürütülür. Bu sorgu, tüm Employé varlıklarının SS, Soyadı ve Adı alanlarını ister. Bir nesne listesi döndürür. Eğer "select e from Employe e" biçiminde çalışanın tüm verileri istenmiş olsaydı, Employe türünde bir nesne listesi elde edilirdi.
- 7-12. satırlar: Bu nesne listesi, Employe türünde bir nesne dizisine kopyalanır.
- 14. satır: Cotisations türündeki tüm varlıkların listesi istenir. Bu listenin tek bir öğe içerdiği bilinmektedir. Dolayısıyla, katkı payı oranlarını elde etmek için listenin ilk öğesi alınır.
- 7. ve 14. satırlar, sınıfın iki özel alanını başlatır.
2.1.5.4. GetEmploye yönteminin uygulanması
GetEmploye yöntemi, verilen SS numarasına sahip Çalışan varlığını döndürmelidir. Kod şu şekilde olabilir:
[Transaction(ReadOnly = true)]
public Employe GetEmploye(string ss) {
IList<Employe> employés = null;
try {
// sorgu
employés = HibernateTemplate.Find<Employe>("select e from Employe e where e.SS=?", new object[]{ss});
} catch (Exception ex) {
// istisnayı dönüştürüyoruz
throw new PamException(string.Format("Erreur d'accès à la BD lors de la demande de l'employé de n° ss [{0}] : [{1}]", ss, ex.ToString()), 41);
}
// bir çalışan bulundu mu?
if (employés.Count == 0) {
// durum bildiriliyor
throw new PamException(string.Format("L'employé de n° ss [{0}] n'existe pas", ss), 42);
} else {
return employés[0];
}
}
- 6. satır: Belirli bir SS numarasına sahip çalışanların listesini alır
- 12. satır: normalde çalışan mevcutsa, tek öğeli bir liste elde edilmelidir
- 14. satır: Aksi takdirde bir istisna atılır
- 16. satır: Eğer öyleyse, listedeki ilk çalışanı döndürürüz
2.2. [dao] katmanı testleri
2.2.1. Visual Studio projesi
Visual Studio projesi daha önce tanıtılmıştı. Hatırlayalım:
![]() |
- [1] dosyasında, projenin tamamı
- [2]'te, projenin çeşitli sınıfları. [tests] klasörü, bir konsol testi [Main.cs] ve bir birim testi [NUnit.cs] içerir.
- [3] dosyasında, [Main.cs] programı derlenmiştir.
![]() |
- [4]'te, [NUnit.cs] dosyası oluşturulmaz.
- Proje bir konsol uygulamasıdır. Yürütülen sınıf, [5]'te belirtilen, [Main.cs] dosyasının sınıfıdır.
2.2.2. [Main.cs] konsol test programı
[Main.cs] test programı aşağıdaki mimaride çalıştırılır:
![]() |
[IPamDao] arayüzünün yöntemlerini test etmekle görevlidir. Basit bir örnek şu şekilde olabilir:
using System;
using Pam.Dao.Entites;
using Pam.Dao.Service;
using Spring.Context.Support;
namespace Pam.Dao.Tests {
public class MainPamDaoTests {
public static void Main() {
try {
// [dao] katmanının örneklenmesi
IPamDao pamDao = (IPamDao)ContextRegistry.GetContext().GetObject("pamdao");
// çalışan kimlik listesi
foreach (Employe Employe in pamDao.GetAllIdentitesEmployes()) {
Console.WriteLine(Employe.ToString());
}
// bir çalışan ve ödenekleri
Console.WriteLine("------------------------------------");
Console.WriteLine(pamDao.GetEmploye("254104940426058"));
Console.WriteLine("------------------------------------");
// prim listesi
Cotisations cotisations = pamDao.GetCotisations();
Console.WriteLine(cotisations.ToString());
} catch (Exception ex) {
// istisna ekranı
Console.WriteLine(ex.ToString());
}
//ara
Console.ReadLine();
}
}
}
- 11. satır: Spring'den [dao] katmanına ilişkin bir referans istenir.
- 13-15. satırlar: [IPamDao] arayüzünün [GetAllIdentitesEmployes] yönteminin test edilmesi
- 18. satır: [IPamDao] arayüzünün [GetEmploye] yönteminin test edilmesi
- 21. satır: [IPamDao] arayüzündeki [GetCotisations] yönteminin testi
Spring, NHibernate ve log4net, 2.1.4.1. paragrafında incelenen [App.config] dosyası tarafından yapılandırılır.
1.2 numaralı paragrafta açıklanan veritabanı kullanılarak yapılan çalıştırma, konsolda aşağıdaki sonucu verir:
- 1-2. satırlar: [Employe] türündeki 2 çalışan; yalnızca [SS, Nom, Prenom] bilgileri mevcuttur
- 4. satır: [Employe] türündeki ve [254104940426058] sosyal güvenlik numarasına sahip çalışan
- 5. satır: prim oranları
2.2.3. NUnit ile birim testleri
Şimdi NUnit ile bir birim testine geçiyoruz. [dao] katmanının Visual Studio projesi şu şekilde değişecektir:
![]() |
- 'den [1]'e, test programı [NUnit.cs]
- [2,3]'e, proje DLL adlı bir dosya oluşturacak ve bu dosya [pam-dao-spring-nhibernate.dll] olarak adlandırılacak
- [4]'e, NUnit çerçevesinin DLL referansı: [nunit.framework.dll]
- [5]'e dönüştürüldüğünde, [Main.cs] sınıfı DLL'e dahil edilmeyecek [pam-dao-spring-nhibernate]
- [6]'e dönüştürüldüğünde, [NUnit.cs] sınıfı DLL ve [pam-dao-spring-nhibernate]'e dahil edilecektir
NUnit test sınıfı şöyledir:
using System.Collections;
using NUnit.Framework;
using Pam.Dao.Service;
using Pam.Dao.Entites;
using Spring.Objects.Factory.Xml;
using Spring.Core.IO;
using Spring.Context.Support;
namespace Pam.Dao.Tests {
[TestFixture]
public class NunitPamDao : AssertionHelper {
// test edilecek [dao] katmanı
private IPamDao pamDao = null;
// oluşturucu
public NunitPamDao() {
// [dao] katmanının örneklenmesi
pamDao = (IPamDao)ContextRegistry.GetContext().GetObject("pamdao");
}
// başlatma
[SetUp]
public void Init() {
}
[Test]
public void GetAllIdentitesEmployes() {
// çalışan sayısı kontrolü
Expect(2, EqualTo(pamDao.GetAllIdentitesEmployes().Length));
}
[Test]
public void GetCotisations() {
// prim oranının kontrolü
Cotisations cotisations = pamDao.GetCotisations();
Expect(3.49, EqualTo(cotisations.CsgRds).Within(1E-06));
Expect(6.15, EqualTo(cotisations.Csgd).Within(1E-06));
Expect(9.39, EqualTo(cotisations.Secu).Within(1E-06));
Expect(7.88, EqualTo(cotisations.Retraite).Within(1E-06));
}
[Test]
public void GetEmployeIdemnites() {
// bireylerin doğrulanması
Employe employe1 = pamDao.GetEmploye("254104940426058");
Employe employe2 = pamDao.GetEmploye("260124402111742");
Expect("Jouveinal", EqualTo(employe1.Nom));
Expect(2.1, EqualTo(employe1.Indemnites.BaseHeure).Within(1E-06));
Expect("Laverti", EqualTo(employe2.Nom));
Expect(1.93, EqualTo(employe2.Indemnites.BaseHeure).Within(1E-06));
}
[Test]
public void GetEmployeIdemnites2() {
// mevcut olmayan kişi kontrolü
bool erreur = false;
try {
Employe employe1 = pamDao.GetEmploye("xx");
} catch {
erreur = true;
}
Expect(erreur, True);
}
}
}
- 11. satır: Sınıf, onu bir [NUnit] test sınıfı yapan [TestFixture] özniteliğine sahiptir.
- 12. satır: Sınıf, NUnit çerçevesinin (2.4.6 sürümünden itibaren) AssertionHelper yardımcı sınıfından türetilmiştir.
- 14. satır: Özel alan [pamDao], katman erişim arayüzü [dao]'in bir örneğidir. Bu alanın türünün bir sınıf değil, bir arayüz olduğu unutulmamalıdır. Bu, [pamDao] örneğinin yalnızca [IPamDao] arayüzüne ait yöntemlere erişim sağladığı anlamına gelir.
- Sınıfta test edilen yöntemler, [Test] özniteliğine sahip olanlardır. Tüm bu yöntemler için test süreci şu şekildedir:
- Öncelikle [SetUp] özniteliğine sahip yöntem çalıştırılır. Bu yöntem, test için gerekli kaynakları (ağ bağlantıları, veritabanı bağlantıları vb.) hazırlamak için kullanılır.
- Ardından test edilecek yöntem çalıştırılır
- ve son olarak [TearDown] özniteliğine sahip yöntem çalıştırılır. Bu yöntem genellikle [SetUp] özniteliğine sahip yöntem tarafından kullanılan kaynakları serbest bırakmak için kullanılır.
- Testimizde, her testten önce tahsis edilecek ve sonrasında serbest bırakılacak kaynaklar bulunmamaktadır. Dolayısıyla, [SetUp] ve [TearDown] özniteliklerine sahip yöntemlere ihtiyacımız yoktur. Örnek olarak, 23-26. satırlarda [SetUp] özniteliğine sahip bir yöntem gösterdik.
- 17-20. satırlar: Sınıf oluşturucu, Spring ve [App.config] yardımıyla [pamDao] özel alanını başlatır.
- 29-32. satırlar: [GetAllIdentitesEmployes] yöntemini test eder
- 35-42. satırlar: [GetCotisations] yöntemini test eder
- 45-53. satırlar: [GetEmploye] yöntemini test eder
- satır 56-65: bir istisna durumunda [GetEmploye] yöntemini test eder.
Projenin derlenmesi sırasında DLL ve [pam-dao-spring-nhibernate.dll] dosyaları, [bin/Release] klasöründe oluşturulur:
![]() |
DLL ve [pam-dao-spring-nhibernate.dll] dosyalarını [NUnit-Gui] aracı (sürüm 2.5) ile yüklüyoruz ve testleri gerçekleştiriyoruz:

Yukarıda, testler başarıyla tamamlanmıştır.
2.2.4. [dao] katmanınd 'in DLL'e dönüştürülmesi
[PamDaoNHibernate] sınıfı yazıldıktan ve test edildikten sonra, [dao] katmanından DLL şu şekilde oluşturulacaktır:
![]() |
- [1], test programları proje derlemesinden hariç tutulur
- [2,3], proje yapılandırması
- [4], proje oluşturma
- DLL dosyası, [bin/Release] [5] klasöründe oluşturulur.











