13. [SimuPaie] uygulaması – sürüm 9 – Spring entegrasyonu / NHibernate
Burada, sürüm 7 [pam-v7-3tier-nhibernate-multivues-multipages]'teki üç katmanlı ASP.NET uygulamasını ele alacağız. Uygulamanın katmanlı mimarisi şu şekildeydi:
![]() |
Yukarıda, [dao] katmanı, NHibernate çerçeve yapısı ile uygulanmıştı. Spring çerçevesi yalnızca katmanlar arası entegrasyon için kullanılmıştır. Spring çerçevesi, Nhibernate çerçevesi ile çalışmak için yardımcı sınıflar sunar. Bu sınıfların kullanılması, [dao] katmanının kodunun yazılmasını kolaylaştırır. Önceki mimari şu şekilde gelişmiştir:
![]() |
Kullanılan katmanlı yapı nedeniyle, Spring / NHibernate entegrasyonunun kullanılması, yalnızca [dao] katmanında değişiklik yapılmasını gerektirir. [presentation] (web / ASP.NET) ve [metier] katmanlarının değiştirilmesine gerek kalmayacaktır. İşte Spring tarafından entegre edilen katmanlı mimarilerin en büyük avantajı budur.
Bundan sonra, işlevsel bir çözümün kodunu inceleyerek [dao] katmanını [Spring / NHibernate] ile birlikte 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 ve [http://www.springframework.net/documentation.html] (Haziran 2010) belgelerinden yararlanarak önerilen çözümü kendi sorunlarına uyarlayabilir.
[dao] ve [metier] katmanlarının oluşturulmasında izlenen yaklaşım, 7. paragrafta açıklanan sürüm 3’tür. [présentation] katmanı için izlenen yaklaşım ise 11. paragrafta açıklanan sürüm 7’dir.
13.1. Veriye erişim katmanı [dao]
![]() |
13.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 NHibernate varlıklarının yapılandırmasını içerir
- [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, [pam-dao-nhibernate] projesinde incelenen NHibernate varlıklarını buluyoruz
- [service] klasöründe ise [IPamDao] arayüzünü ve Spring çerçeve ile gerçekleştirilmiş olan NHibernate ve [PamDaoSpringNHibernate] uygulamalarını buluyoruz. [IPamDao] arayüzünün bu yeni uygulamasını yazmamız gerekecek
- [tests] klasörü, [pam-dao-nhibernate] projesiyle aynı testleri içerir. Bu testler, aynı [IPamdao] arayüzünü test eder.
- [3]'te proje referansları bulunur. Spring / NHibernate entegrasyonu için iki yeni DLL, [Spring.Data] ve [Spring.Data.NHibernate12] gereklidir. Bu DLL bileşenleri, Spring.Net çerçeve yapısında mevcuttur. Bunlar, DLL ve [4] bileşenlerinin bulunduğu [lib] klasörüne eklenmiştir:
![]() |
Projenin [3] referanslarında, aşağıdaki DLL referansları bulunur:
- NHibernate: ORM için NHibernate
- MySql.Data: SGBD ve MySQL için ADO.NET sürücüsü
- 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.Data ve Spring.Data.NHibernate12: Spring / NHibernate desteğini sağlar.
Bu referanslar [lib] ve [4] klasörlerinden alınmıştır. Tüm bu referansların "Yerel Kopya" özelliğinin "True" olarak ayarlandığından emin olunmalıdır. [5]:
13.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.
13.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, [pam-dao-nhibernate] projesininkilerle aynıdır; tek fark, NHibernate yapılandırma dosyalarındaki farklılıktı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 şu şekildedir:
<?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>
- 2. satır: assembly özniteliği, [Employe.hbm.xml] dosyasının [pam-dao-spring-nhibernate] derlemesinde bulunacağını belirtir
13.1.4. Spring / NHibernate Yapılandırması
Visual C# projesine geri dönelim:
![]() |
- [1]'te, [App.config] ve [Dao.xml] dosyaları Spring / NHibernate entegrasyonunu yapılandırır
13.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 / NHibernate yapılandırması bu dosyada bulunacaktır.
13.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.NHibernate12">
<property name="DbProvider" ref="DbProvider"/>
<property name="MappingAssemblies">
<list>
<value>pam-dao-spring-nhibernate</value>
</list>
</property>
<property name="HibernateProperties">
<dictionary>
<entry key="hibernate.dialect" value="NHibernate.Dialect.MySQLDialect"/>
<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.NHibernate12">
<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.NHibernate12 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: NHibernate tarafından yönetilen varlıkları yapılandıran [*.hbm.xml] dosyalarını içeren derleme listesini belirler. 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 özelliğinin true olarak ayarlanması, 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.NHibernate12 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’in SessionFactory’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şleminden önce
- 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ği ile başlatılacak olan HibernateTemplate özelliğine sahip olacaktır.
13.1.5. [dao] katmanının uygulaması
13.1.5.1. Uygulama sınıfının iskeleti
[IPamDao] arayüzü, [pam-dao-nhibernate] projesindekiyle aynıdır:
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 (singleton) olarak oluşturulur. Ad alanlarının isimlerinin bu şekilde seçilmesinin nedeni budur.
- 4. satır: Arayüzün adı [IPamDao]'tir. Bu arayüz üç yöntem tanımlar:
- 6. satır: [GetAllIdentitesEmployes], [Employe] türünde bir nesne dizisi döndürür; bu dizi, çocuk bakıcılarının listesini basitleştirilmiş bir biçimde (soyadı, adı, SS) temsil eder.
- 8. satırda, [GetEmploye], [Employe] nesnesini döndürür: bu nesne, yönteme parametre olarak geçirilen sosyal güvenlik numarasına sahip çalışanı ve endeksine bağlı ödenekleri içerir.
- 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 desteği ile bu arayüzün uygulama sınıfının iskeleti / NHibernate ş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() {
...
}
// nesneyi silme
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 primleri
[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.
13.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:
IList<T> Find<T>(string requete_hql) | HQL sorgusunu yürütür ve T türünde bir nesne listesi döndürür |
IList<T> Find<T>(string requete_hql, object[]) | ? ile parametreleştirilmiş bir HQL sorgusunu yürütür. Bu parametrelerin değerleri, nesne dizisi tarafından sağlanır. |
IList<T> LoadAll<T>() | 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:
T Load<T>(object id) | id birincil anahtarına sahip T türündeki varlığı NHibernate oturumuna ekler. |
void SaveOrUpdate(object entite) | 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 yer alır. |
void Delete(object entite) | entité nesnesini NHibernate oturumundan siler. |
13.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.
13.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) {
// istisna dönüştürülüyor
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 geri kazanıldı mı?
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 varsa, listenin ilk çalışanı döndürülür
13.1.5.5. Conclusion
[dao] katmanındaki kodu,
- tek başına NHibernate
- kullanıldığında
kullanıldığında, ikinci çözümün daha basit kod yazılmasını sağladığını görüyoruz.
13.2. [dao] katmanının testleri
13.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 farklı 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.
13.2.2. [Main.cs] konsol test programı
[Main.cs] test programı aşağıdaki mimaride çalıştırılır:
![]() |
Bu program, [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 örneği oluşturuluyor
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 testi
- 21. satır: [IPamDao] arayüzündeki [GetCotisations] yönteminin testi
Spring, NHibernate ve log4net, 13.1.4.1. paragrafında incelenen [App.config] dosyası tarafından yapılandırılır.
6.2. 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ı
13.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, DLL'e yapılan referans NUnit'e: [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ı şu şekildedir:
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 doğrulanması
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() {
// var olmayan kişi kontrolü
bool erreur = false;
try {
Employe employe1 = pamDao.GetEmploye("xx");
} catch {
erreur = true;
}
Expect(erreur, True);
}
}
}
Bu sınıf, 7.3.4. paragrafında daha önce incelenmiştir.
Proje oluşturma işlemi, [bin/Release] klasöründe DLL ve [pam-dao-spring-nhibernate.dll] dosyalarını oluşturur.
![]() |
DLL ve [pam-dao-spring-nhibernate.dll] dosyaları, 2.4.6 sürümündeki [NUnit-Gui] aracıyla yüklenir ve testler gerçekleştirilir:

Yukarıda, testler başarıyla tamamlanmıştır.
Uygulama ödevi:
[PamDaoSpringNHibernate] sınıfındaki testleri makinede uygulayın.- Diğer SGBD sunucularını (Firebird, MySQL; Postgres, SQL) kullanmak için farklı [Dao.xml] yapılandırma dosyalarını kullanın
13.2.4. [dao] katmanınd 'in DLL'te oluşturulması
[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] ve [5] klasörlerinde oluşturulur. Bunu, [lib] [6] klasöründe zaten bulunan DLL dosyasına ekliyoruz:
![]() |
13.3. İş katmanı
[SimuPaie] uygulamasının genel mimarisine geri dönelim:
![]() |
Artık [dao] katmanının hazır olduğunu ve DLL [pam-dao-spring-nhibernate.dll] içinde kapsüllendiğini varsayıyoruz. Şimdi [metier] katmanına odaklanacağız. İş kurallarını, bu örnekte maaş hesaplama kurallarını uygulayan katman budur.
İş katmanının Visual Studio projesi aşağıdaki gibi görünebilir:
![]() |
- [1] dosyasında, [App.config] ve [Dao.xml] dosyalarıyla yapılandırılmış projenin tamamı yer almaktadır. [App.config] dosyası, [dao] ve [pam-dao-spring-nhibernate] katmanındaki projede olduğu gibi aynıdır. Aynı durum [Dao.xml] dosyası için de geçerlidir; tek fark, bu dosyada pammetier kimliğine sahip ek bir Spring nesnesi tanımlanmış olmasıdır. Bu nesnenin tanımlaması, [pam-metier-dao-nhibernate] projesindeki [App.config] dosyasında olduğu gibidir.
- [2] dosyasında, [pam] klasörü, [pam-metier-dao-nhibernate] projesinin [metier] katmanındaki haliyle aynıdır
- [3] katmanında, proje tarafından kullanılan referanslar yer almaktadır. Daha önce incelenen [dao] katmanındaki DLL ve [pam-dao-spring-nhibernate] referanslarına dikkat edilmelidir.
Soru: Yukarıdaki [pam-metier-dao-spring-nhibernate] projesini oluşturun. Proje ayrı ayrı test edilecektir:
-
konsol modunda, [Main.cs] konsol programı tarafından
-
NUnit çerçeve programı tarafından yürütülen [NUnit.cs] birim testi ile
Yeni [pam-metier-dao-spring-nhibernate] projesi, [pam-metier-dao-nhibernate] projesinin basitçe kopyalanması ve ardından değiştirilmesi gereken öğelerin düzenlenmesi yoluyla oluşturulabilir.
Testlerin ardından, [metier] katmanından DLL oluşturulacak ve buna [pam-metier-dao-spring-nhibernate] adı verilecektir:
![]() |
- [1]'e, NUnit testi başarılı
- [2]'e dönüştürüldü; proje tarafından oluşturulan DLL
[metier] katmanındaki DLL dosyası, [lib] klasöründe halihazırda bulunan DLL dosyasına eklenecek [3]:
![]() |
13.4. [web] katmanı
[SimuPaie] uygulamasının genel mimarisine geri dönelim:
![]() |
[dao] ve [métier] katmanlarının oluşturulduğunu ve DLL ile [pam-dao-spring-nhibernate, pam-metier-dao-spring-nhibernate] içinde kapsandığını varsayıyoruz. Şimdi web katmanını açıklayalım.
[web] katmanına ait Visual Web Developer projesi, öncelikle [pam-v7-3tier-nhibernate-multivues-multipages] web projesinin klasörünün basitçe kopyalanmasıyla elde edilir. Ardından projenin adı [pam-v9-3tier-spring-nhibernate-multivues-multipages] olarak değiştirilir:
![]() |
Yeni [pam-v9-3tier-spring-nhibernate-multivues-multipages] web projesi, [pam-v7-3tier-nhibernate-multivues-multipages] projesinden aşağıdaki noktalarda farklılık gösterir:
- [1]'te, yapılandırma [Dao.xml] ve [Web.config] dosyalarıyla yapılmıştır. [Dao.xml], [pam-v7]'te mevcut değildi ve [Web.config] dosyası Spring / NHibernate yapılandırmasını içermelidir; oysa [pam-v7]'te, sadece NHibernate yapılandırılıyordu.
- [2]'te, [dao] ve [metier] katmanlarının DLL dosyaları, az önce oluşturduğumuz dosyalardır.
[Dao.xml] dosyası, [metier] katmanının oluşturulmasında kullanılan dosyadır. [Web.config] dosyası ise, [pam-v7] katmanına Spring yapılandırması / NHibernate yapılandırmasının eklendiği [pam-v7] dosyasına ait olan dosyadır. [pam-v9] dosyasının içindeki [Web.config] dosyası şöyledir:
<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
........
</sectionGroup>
<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>
............. le reste est identique au fichier [Web.config] de [pam-v7]
7-11 ve 16-23. satırlarda, daha önce oluşturulmuş [dao] ve [metier] katmanlarının [App.config] dosyalarında bulunan Spring yapılandırması yer almaktadır; tek bir farkla: [App.config] dosyalarında 17. satır şu şekilde yazılmıştı:
<resource uri="Dao.xml" />
Aşağıdaki yapılandırma ile:
![]() |
[Dao.xml] dosyası, web projesi klasöründeki [bin] klasörüne kopyalanır. Aşağıdaki sözdizimiyle
<resource uri="Dao.xml" />
sözdizimiyle, [Dao.xml] dosyası, web uygulamasını çalıştıran işlemin geçerli klasöründe aranacaktır. Ancak bu klasör, çalıştırılan web projesi klasöründeki [bin] klasörü değildir. Şu şekilde yazılmalıdır:
<resource uri="~/Dao.xml" />
yazılmalıdır; böylece [Dao.xml] dosyası, çalıştırılan web projesinin klasöründeki [bin] klasöründe aranacaktır.
Soru: Bu web uygulamasını bir bilgisayarda çalıştırmak.
13.5. Conclusion
Şu mimariden geçtik:
![]() |
mimariye:
![]() |
Burada, Spring tarafından NHibernate'in entegrasyonunun sağladığı olanaklardan yararlanarak [dao] katmanını uygulamaya koymak söz konusuydu.
Bunun:
- [dao] katmanını etkilediğini gördük. Bu katmanı yazmak daha kolaydı, ancak daha karmaşık bir Spring yapılandırması gerektirdi.
- [metier] ve [web] katmanlarını da kısmen etkiledi
Bu, katmanlı mimarilerin önemini gösteren bir başka örnek oldu.























