Skip to content

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:

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)
NHibernate oturumuna, birincil anahtarı id olan T türündeki varlığı ekler.
void SaveOrUpdate(object entité)
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.
void Delete(object entité)
, 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
3
4
5
6
[254104940426058,Jouveinal,Marie,,,,]
[260124402111742,Laverti,Justine,,,,]
------------------------------------
[254104940426058,Jouveinal,Marie,5 rue des oiseaux,St Corentin,49203,[2, 2,1, 2,1, 3,1, 15]]
------------------------------------
[3,49,6,15,9,39,7,88]
  • 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:

Image

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.