15 Ocak 2009 Perşembe

Asenkron Programlama 2

Bir önceki makalemizde Asenkron programlama tekniklerinden WaitAny tekniğini incelemiştik. Bu makalemizde ise öncelikle WaitOne daha sonra ise WaitAll teknikleri üzerinde duruyor olacağız.

WaitOne Tekniği
Bu tekniğimizde uygulama tek bir SQL komutu için bekletilir. Bu aşamada bu tekniği sadece bir cümle ile açıklayıp hemen örneğimiz üzerinden ilerleyelim. Örneğimizde veritabanımızdaki iki ayrı tabloda güncelleme yapıyor ve bu işlemlerden birinin erken bitmesine rağmen diğerini beklediğini görüyor olacağız.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace Wait_One
{
class Program
{
static void Main(string[] args)
{
//SqlConnection nesnelerimizi oluşturuyoruz.
SqlConnection con1 = new SqlConnection("data source=.;initial catalog=AdventureWorks; integrated security=true;async=true");
SqlConnection con2 = new SqlConnection("data source=.;initial catalog=AdventureWorks; integrated security=true;async=true");

//SqlCommand nesneleri aracılığıyla sorgu ifadelerimizi yazıyor ve birini 10,diğerini 20 saniye bekletiyoruz.
SqlCommand cmd1 = new SqlCommand("waitfor delay '0:0:20'update Person.Contact set FirstName=FirstName", con1);
SqlCommand cmd2 = new SqlCommand("waitfor delay '0:0:10'; update HumanResources.Employee set Title=Title", con2);

//Baglantilarımız açıyoruz.
con1.Open();
con2.Open();

//Asenkron işlemimizin toplam ne kadar sürdüğünü görebilmek için uygulama başlar başlamaz bir DateTime tanımlıyoruz ve uygulamanın başladığı anın değerini alıyoruz.
DateTime simdi = DateTime.Now;

//Asenkron çalışacak işlemlerimiz.Fakettiğiniz üzere senkron işleyişten farklı olarak SqlCommand nesnelerinin metotlarının başında Begin ve End ifadeleri yer alıyor.
IAsyncResult res1 = cmd1.BeginExecuteNonQuery();
IAsyncResult res2 = cmd2.BeginExecuteNonQuery();

//Iki SqlCommand birbirlerini beklemesi için :
res1.AsyncWaitHandle.WaitOne();
res2.AsyncWaitHandle.WaitOne();

//Güncellemeler sonucu etkilenen kayıt sayısını alıyoruz.
int etkilenen = cmd1.EndExecuteNonQuery(res1);
int etkilenen2 = cmd2.EndExecuteNonQuery(res2);

//Uygulamamızın bittiği anın değerini alıyoruz.
DateTime sonra = DateTime.Now;

//Baglantıları kapatıyoruz.
con1.Close();
con2.Close();

//Ekrana Yazdırıyoruz.
Console.WriteLine("Person.Contact Tablosunda {0} kayit güncellendi..", etkilenen);
Console.WriteLine("Human Resources Employee Tablosunda {0} kayit güncellendi", etkilenen2);

//Uygulamanın son anından ilk anın çıkarıp geçen süreyi hesaplıyoruz ve ekrana gösteriyoruz.
TimeSpan fark = sonra - simdi;
Console.WriteLine("Gecen Zaman : {0}", fark.TotalSeconds);

}
}
}

Uygulamamızı çalıştırıp sonucu görüyoruz.


Gördüğümüz gibi iki sonucumuzda aynı anda başladı ve ilk biten işlemimiz diğer SQL komutunu da bekledi ve sonuç olarak iki işlemimizde aynı anda ekrana geldi. Uygulamanın toplam çalışma zamanı olan 20 saniye de geç bitmesi için bizim manuel olarak beklettiğimiz işlemin süresidir.
WaitAll Tekniği
Bu tekniğimiz adından da anlaşıldığı üzere tüm işlemlerin bitmesinin beklendiği hepsinin aynı anda bitirildiği tekniktir. Bu uygulamamıza ait örneğimizle tekniğimizi incelemeye başlayalım.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Threading;

namespace WaitALL_Teknigi
{
class Program
{
static void Main(string[] args)
{
string conStr = "data source=.;initial catalog=AdventureWorks;Integrated security=true;async=true";

//Baglantılar
SqlConnection con1 = new SqlConnection(conStr);
SqlConnection con2 = new SqlConnection(conStr);
SqlConnection con3 = new SqlConnection(conStr);

//SQLCommand ifadeleri
SqlCommand cmd1 = new SqlCommand("waitfor delay '0:0:20';select Name from Production.Product", con1);
SqlCommand cmd2 = new SqlCommand(" waitfor delay '0:0:10';update Production.Product set Color='Black' where Color='Siyah'", con2);
SqlCommand cmd3 = new SqlCommand("waitfor delay '0:0:5';update Person.Contact set FirstName=FirstName", con3);

con1.Open();
con2.Open();
con3.Open();

DateTime once = DateTime.Now;
//Asenkron Isleyis
IAsyncResult res1=cmd1.BeginExecuteReader();
IAsyncResult res2 = cmd2.BeginExecuteNonQuery();
IAsyncResult res3 = cmd3.BeginExecuteNonQuery();

//WaitHandle.WaitAll() metodunu bizden isteyecegi ve hangi uygulamanin bittigi bilgisinin kontrol edilmesini yardimci dizimiz.
WaitHandle[] handler = new WaitHandle[] { res1.AsyncWaitHandle, res2.AsyncWaitHandle, res3.AsyncWaitHandle };

WaitHandle.WaitAll(handler);
// Asenkron Başlatilan Islemleri Teker Teker Alalim
SqlDataReader dr=cmd1.EndExecuteReader(res1);
while (dr.Read())
{
Console.WriteLine(dr.GetString(0));
}
dr.Close();
con1.Close();

// Ikinci Asenkron Başlatilan Islemin Sonucunu Alalim
int etkilenen1=cmd2.EndExecuteNonQuery(res2);
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine("Production.Product Tablosunda {0} kayit etkilendi", etkilenen1);
Console.WriteLine("--------------------------------------------------------------");
con2.Close();

// Ucuncu Asenkron Başlatilan islemin sonucunu alalim

int etkilenen2 = cmd3.EndExecuteNonQuery(res3);
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine("Person.Contact Tablosunda {0} kayit etkilendi", etkilenen2);
Console.WriteLine("--------------------------------------------------------------");
con3.Close();

DateTime sonra = DateTime.Now;

TimeSpan fark = sonra - once;
Console.WriteLine("Gecen Zaman {0} saniyedir", fark.TotalSeconds);

}
}
}
Son olarak sonucumuza da bir göz atalım.


Üç işlemimizde farklı sürelerde bitmesine rağmen son biten işlemi de bekleyip hep birlikte ekrana geldiler. Uygulamanın çalışma süresi de doğal olarak son biten işlemin süresine denk oldu. Bu teknikte bir uygulamanın bir fazla thread ile çalışması ve kullanıcıyla işlemlerin sonucunun aynı anda gösterilmesi istenilen durumlarda kullanılabilecek bir tekniktir.

Asenkron programlamanın iki tekniği incelemeye çalıştıktık. Bir sonraki makalemizde diğer teknik olan CallBack ve Pooling tekniklerini de inceleyerek Asenkron Programlama konusu bitirmiş olacağız.

Faydası olması Dileğiyle.
Herkese İyi Çalışmalar.

Asenkron Programlama-1

Klasik programlama tarzı olan senkron programlamada uygulamamızda bir işlem başlaması için diğer bir işlemin bitmiş olması yani uygulamadaki thread’in boş olması gerekmektedir. Daha açıklayıcı olması açısında bir örnek verecek olursak veritabanından gelen verinin listbox gibi bir kontrole dolması esnasında bir butona basmak veya formun boyutu vs. değiştirmek mümkün olmayacaktır. Uygulamamızda herhangi bir anında yalnızca işlem çalışacaktır.
Asenkron programlamada ise uygulama ana thread’ine ek olarak yan threadler açılarak uygulamanın birden fazla thread ile çalışmasını sağlayabilir ve böyle birden fazla işlemin birbirlerinden bağımsız çalışmasını sağlayabiliriz. Bunu trafiğin yoğun ve sıkışık olduğu bir bölgede yolun açılması için ekstra şeritlerin trafiğe açılması gibi düşünebiliriz. Yoğun veri transferini olduğu bir işlemi açılan yeni thread’e alıp diğer işlemleri ana threadden gerçekleştirmek gibi çözümler üretilebilmesini sağlayan Asenkron programlamadır. Asenkron programlama da birbirinden farklı özellikleri olan birden fazla Asenkron programlama tekniği kullanmaktadır. Giriş kısmını fazla uzatmadan bu teknikleri incelemeye başlayalım.
Wait Any Tekniği
Adından da anlayabileceğimiz gibi bu teknikte birden fazla işlem aynı anda başlar ve işlemlerin hiçbiri birbirini beklemez. Şimdi bir örnekle bu tekniği daha açıklayıcı bir hale getirelim.
Bu örneğimizde bir konsol uygulamasında veritabanına bağlanıp AdventureWorks tablosunda sorgulama ve güncelleme işlemleri yapıp sonuçları ekrana yazdıracağız.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Threading;

namespace Wait_Any_Teknigi
{
class Program
{
static void Main(string[] args)
{
//Ilk olarak string bir değişken üzerinden baglanti cümlemizi tanımlıyoruz.Askenron uygulamamız sorunsuz çalışması için async=true ifadesini eklememiz gereklidir.
string conStr = "data source=.;initial catalog=AdventureWorks;integrated security=true;async=true";

//Üç farklı bağlantıyı aynı anda başlatacağımızdan dolayı 3 farklı SqlConnection nesnesi yaratıyoruz.
SqlConnection con1 = new SqlConnection(conStr);
SqlConnection con2 = new SqlConnection(conStr);
SqlConnection con3 = new SqlConnection(conStr);

//3 Farklı SqlConnection nesnesi üzerinden 3 farklı SqlCommand tanımlayıp Asenkron çalışma mantığını rahat görebilmek için bu üç SqlCommand nesnesini de farklı sürelerde bekletiyoruz.Bu sayede her bir sorgu beşer saniye aralıkla gelecektir.
SqlCommand cmd1 = new SqlCommand("waitfor delay '0:0:15';select Name from Production.Product", con1);
SqlCommand cmd2 = new SqlCommand("waitfor delay '0:0:10';update HumanResources.Employee set Title=Title", con2);
SqlCommand cmd3 = new SqlCommand("waitfor delay '0:0:5'; update Person.Contact set FirstName=FirstName", con3);

//Baglantılarınızı açıyoruz.
con1.Open();
con2.Open();
con3.Open();

// Islemler Asenkron olarak başlatılıyor.IAsyncResult arayüzü asenkron işlemleri yürüten metotların bulunduğu sınıflar tarafından implement edilmelidir.
IAsyncResult res1= cmd1.BeginExecuteReader();
IAsyncResult res2 = cmd2.BeginExecuteNonQuery();
IAsyncResult res3 = cmd3.BeginExecuteNonQuery();

//IAsyncResult arayüzünün AsyncWaitHandle özelliğini kullanarak bir dizi yaratıyoruz.Burdaki amacimiz daha sonra çağıracağımız ilgili metotun bizden WaitHandle tipinden bir dizi istemesi ver bu dizi yardımıyla sürekli işlemleri kontrol altına alıp bitip bitmediklerini kontrol etmesidir.
WaitHandle[] handlerlar = new WaitHandle[] { res1.AsyncWaitHandle, res2.AsyncWaitHandle, res3.AsyncWaitHandle };

//Biten işlemin dizinin hangi indeksindeki işlemi olduğu tutacağımız değişkenimizi tanımlıyoruz.
int etkilenen = 0;
//handlerlar dizisinin yani asenskron yürüteceğimiz işlem sayısı kadar dönecek bir for döngüsü kuruyoruz
for (int i = 0; i < handlerlar.Length; i++)
{
//WaitHandle sınıfını kullanarak handlerler dizisi içerisinde temsil edilen işlemlerde WaitAny tekniğin kullanacağımızı bildiriyor ve hangi işlem bittiyse onun indeks numarasını etkilenen değişkeni üzerine alıyoruz
etkilenen = WaitHandle.WaitAny(handlerlar);
//Etkilenen değişkenin değerine gore if sorgumuzu yaziyoruz.Böylece ilk biten işlem hangisi ise etkilenen değişken onun indeks değerine sahip olup gerekli islemi yapacaktır.Aynı işlemler daha sonra ikinci ve üçüncü biten işlemler için uygulanacaktır.Böylece her biten işlem bir diğerini beklemeden sonucu ekrana yazdıracaktır.
if (etkilenen == 0)
{
SqlDataReader dr = cmd1.EndExecuteReader(res1);
while (dr.Read())
{
Console.WriteLine(dr[0].ToString());
}
dr.Close();
con1.Close();
}
else if (etkilenen == 1)
{
int etkilenenKayitSayisi = cmd2.EndExecuteNonQuery(res2);
Console.WriteLine("HumanResources.Employee {0} kayit Etkilendi", etkilenenKayitSayisi);
con2.Close();
}
else if(etkilenen==2)
{
int etkilenenKayitSayisi = cmd3.EndExecuteNonQuery(res3);
Console.WriteLine("Person.Contact {0} kayit Etkilendi", etkilenenKayitSayisi);
con3.Close();
}
}

}
}
}
Uygulamamız çalıştırıp sonuçlara bir göz atalım.


Uygulamamız çalıştığında ilk biten işlemimiz 5 saniye ertelediğimiz Person.Contact tablosunda update işlemi yapan cmd3isimli nesnedir.


İkinci işlemimiz ise 10 saniye ertelediğimiz Human.Resources.Employee tablosunda update işlemi yapan cmd2 nesnesidir.


Son olarak biten işlem ise Production.Product tablosundaki ürün isimlerini getiren cmd1 nesnesidir.

Gördüğümüz üzere aynı anda başlayan ve ilerleyen üç işlemimiz birbirinden bağımsız asenkron olarak çalışmaktadır. Bir command nesnemiz ürünlerin isimlerini getirirken aynı anda diğer iki command nesnemiz de farklı tablolardaki belirli kolonları güncelleme işlemini yapmaktadır. Bu da bize çok ciddi zaman kazançları sağlamaktadır. En basit hesaplamayla manuel olarak uzattığımız bu üç işlem, senkron işleyiş ile biri bittikten sonra diğerinin başlayacak olması nedeniyle 30 saniye sürecekken asenkron işleyiş ile biz bu süreyi 15 saniyeye indirmiş olduk.
Bir sonraki makalemizde Asenkron programlamanın diğer tekniklerinden WaitAll ve WaitOne tekniklerini inceliyor olacağız.
Umarım faydalı olmuştur.
Herkese İyi Çalışmalar…

12 Ocak 2009 Pazartesi

Linq Nedir?

Bu makalemizde .NET 3.0 ile hayatımıza girmiş ve verilerimizi hızlı bir biçimde SQL sorguları tarzında sorgulayabileceğimiz yapı olan LINQ (Language Integrated Query)’yu inceleyeceğiz.LINQ syntax olarak SQL anımsatan bir yapıdadır.Sanırım LINQ anlatımın en kolay kolu örnek üzerinde ilerlemek olacaktır. Basit bir örnekle LINQ’nun kullanımını incelemeye başlayalım.

İlk olarak örneğimizde Müşteri adlarını, soyadlarını ve firmalarını tuttuğumuz bir diziyi tanımlayacağız. LINQ’yu kullanacağımız yapının mutlaka IEnumerable interface’ini implement etmesi gerekmektedir. Hangi yapıyı kullanırsak kullanalım bu geçerlidir.

var musteri = new[]{
new{MusteriID=1,Adi="Ali",Soyadi="Kaya",Firma="XYZ Yazılım"},
new{MusteriID=2,Adi="Ahmet",Soyadi="Keskin",Firma="ABC Yazılım"},
new{MusteriID=3,Adi="Mehmet",Soyadi="Güzel",Firma="CAN Bilişim"},
new{MusteriID=4,Adi="Hasan",Soyadi="Kara",Firma="OVS Elektronik"},
new{MusteriID=5,Adi="Ayşe",Soyadi="Polat",Firma="ASD Yazılım"}
};

Daha sonra bu müşterilerimizin firma adlarına göre adreslerini tutan başka bir dizi daha tanımlayalım.

var musteriadres = new[]{
new{Firma="XYZ Yazılım",Ulke="Türkiye",Sehir="İstanbul"},
new{Firma="ABC Yazılım",Ulke="Türkiye",Sehir="Ankara"},
new{Firma="CAN Bilisim",Ulke="İngiltere",Sehir="Londra"},
new{Firma="OVS Elektronik",Ulke="Amerika",Sehir="Seattle"},
new{Firma="ASD Yazılım",Ulke="Rusya",Sehir="Moskova"}
};
Şimdi ilk sorgumuzu yazmaya hazırız.Öncelikle basit olarak müşterilerimizin adlarını döndürecek sorgumuzu yazalım.Daha sonra foreach iterasyonu ile sonuçlar içinde dönerek müşteri adlarını ekrana getirelim.

IEnumerable Adlar = musteri.Select(a => a.Adi);
foreach (string ad in Adlar)
{
Console.WriteLine(ad);
}
Şimdi sonuç ekranına bakalım…


Select metodu diziden isteğimiz veriyi elde etmemize olanak sağlar. Peki, nasıl çalışır? Select metodunun parametresi aslında ilgili diziden bir satır alan ve bu satırdaki seçtiğimiz veriyi geri döndüren bir metottur. Bu görevi tamamlayacak metodu kendimizde yazabilir fakat en basit ve kullanışlı teknik lambda (=>) operatörü yardımıyla anonim bir metot çağırmaktır. Burada bilinmesi gereken Select metodunun parametresinde kullandığımız “a” ifadesi metoda gönderilen parametredir. Bu ifadeyi müşteri dizisi içindeki her satırın takma ismi gibi düşünebilirsiniz. Bu takma ismi yerine tanımlı keywordler dışında istediğiniz ifadeyi kullanabilirsiniz.

Şimdi ilk sorgumuzda ufak bir değişiklik yaparak sadece Türkiye’de bulunan müşterilerimizin firmalarının adlarını getirecek sorgumuzu yazalım.

IEnumerable Musteri = musteriadres.Where(adr => String.Equals(adr.Ulke, "Türkiye")).Select(turk => turk.Firma);
foreach (string Turkmusteri in Musteri)
{
Console.WriteLine(Turkmusteri);
}
İşte sonuç ekranımız…

Sorgumuza dönecek olursak musteriadres isimli dizimizde Where ile String.Equal metodunun da yardımıyla ülkesi Türkiye olan firmaları çekip Select sorgumuzda sadece Firma adlarının çekiyoruz.Daha sonrası zaten bildiğimiz foreach iterasyonundan oluşmaktadır.

Peki,sıralama ve gruplama fonksiyonları LINQ’da nasıl gerçekleştiriliyor?Başta da bahsettiğim gibi LINQ ifadeleri syntax olarak SQL sorgularına çok benzemekte.Dilerseniz örnekler yardımıyla bu ifadelerin de nasıl gerçekleştiğine bir göz atalım.

Firma isimlerini alfabetik sırayla getirmek istersek,

IEnumerable alfabetik=musteri.OrderBy(a=>a.Firma).Select(b=>b.Firma);

İşte sıralama işlemi de bu kadar basit…OrderBy ile neyi sıralayacağımızı lambda operatörü yardımıyla belirlerken ikincisi kısımda artık alışık olduğumuz Select sorgumuzu gerçekleştiriyoruz.

Firmalarımızı ülkelerine göre gruplayarak hangi ülkede kaç firma olduğunu ve bu firmaların hangileri olduğunu getirmek istersek eğer;

var ulkeyegoreFirma = musteriadres.GroupBy(ulkesi => ulkesi.Ulke);
foreach (var Ulkesel in ulkeyegoreFirma)
{
Console.WriteLine("Ulkesi : {0}\t{1}",Ulkesel.Key,Ulkesel.Count());
foreach (var firmalar in Ulkesel)
{
Console.WriteLine("\t{0}",firmalar.Firma);
}
}
Bir de sonucumuza bakalım.

LINQ teknolojisine basit bir bakış olarak değerlendirdiğim bu makalemizde sonra olarak sorgu operatörlerini de nasıl kullanacağımızı da görerek makalemizi sonlandıralım.
Şimdi ilk örnekten beri yapmış olduğumuz tarzda sorgumuzu bir daha yazalım.

IEnumerable musteriilkisimleri=
musteri.Select(a=>a.Adi);
Sıra geldi sorgu operatörleriyle aynı sorguyu tekrar yazmaya…

var musteriilkisimleri=from a in musteri
Select a .Adi
Sizler de fark etmişsinizdir bu tarz sorgular nerdeyse SQL ifadeleriyle aynı.

LINQ dünyasına ufak bir giriş yaptığımız bu makalemizin sonuna geldik. Tabii ki LINQ’nun yetenekleri bunlarla sınırlı değildir. Buraya kadar anlattığımız LINQ ‘nun genel bir tanımı ve LINQ to Object dünyasına genel bir bakış niteliğindedir. Bu makalemizi aynı bu makalemiz gibi basit giriş ve birkaç basit örnek içeren LINQ to SQL ve LINQ to XML makaleleri izleyecektir.Daha sonra ise sırasıyla bu üç konuda da orta ve ileri seviye makaleler yazmayı planlıyorum.

Umarım işinize yarayan bir giriş olmuştur.
Şimdilik Hoşcakalın.

11 Ocak 2009 Pazar

Assembly Kavramı

.NET Teknolojilerinde uygulamanın ilgili dilin derleyicisiyle derlenmesi sonucunda oluşan .exe veya .dll uzantili dosya bir assembly içinde yer alır.Bu assembly'nin programlama dili olan assembly ile karıştırılmaması gerekmektedir.Burda bahsi geçen assembly derlenmiş olan .exe veya .dll uzantılı binary dosya ile aynı kavramı ifade etmektedir.Assembly dört bileşenden oluşur.Bunlar CIL, Metadata, Manifesto,Source'dır.CIL(Common Intermediate Language) kaynak kodun derlenmesi sonucunda oluşan ortak ara dildir.Metadata ise assembly üyelerinin listesini barındıran bir çeşit etikettir.Assembly adı,versiyonu,kültür bilgisi gibi bilgileri barındırır.Manifesto bir nevi assembly metadatası olup assembly'nin kendisini tanımlayan bilgilerini içerir.Kaynaklar ise resim,müzik gibi multimedya dosyalarını içeren yapıdır.Basit olarak bir assembly'nin yapısı bu şekildedir.

Private ve Shared Assembly

Genellikle yazdığımız uygulamalara çeşitli nedenlerden ötürü. dll referans ederiz. Uygulamamız bu. dll dosyası içerisindeki kaynak kodları referans alarak çalışmaktadır. Bu nedenle uygulamamıza referans ettiğimiz. dll dosyası silinir veya uygulamanın bulunduğu dizinden  farklı bir dizine taşınırsa uygulamamız hata verecek ve çalışmayacaktır. İşte bu tip. dll dosyalarının oluşturduğu assembly’e Private Assembly denir. Kısaca referans edildiği uygulama ile aynı dizin altında veya bir alt dizinde bulunması zorunlu olan assemblylerdir. Oluşturulan her assembly varsayılan olarak privatedir.
Bazı durumlarda aynı dll dosyasını birden fazla uygulamada kullanmak isteriz. Bunun için dll dosyasını kullanılacağımız uygulamaların bulunduğu dizinlere tek tek kopyalamak gerekecektir. Ve bu durumda aynı Private assemblydeki olduğu gibi sıkıntılar olacak, dll dosyasının silinmesi veya taşınası halinde uygulamamız çalışmayacaktır. Bunun yerine Windows dizini assembly klasörü altında dll dosyalarımızı güvenle tutabileceğimiz bir yapı mevcuttur. Bu yapının adı Global Assembly Cache (GAC) ’dır. Oluşturulan dosyaları GAC’a atmak suretiyle bütün uygulamalarımıza çok rahat bir şekilde referans edebiliriz.Bu şekilde Shared assembly elde etmiş olmaktayız.GAC ‘a direkt olarak kopyalama işlemi yapılamaz.Oluşturulan dll dosyası bir takım işlemlerden geçtikten sonra GAC’a gönderilir.Şimdi bu kurallara göz atalım.Öncelikle dll dosyası bir strong name ‘e sahip olmalıdır.Strong name, public key,assembly versiyon bilgisi,kültür numarasının bir araya gelmesiyle oluşur.Public key değeri, mscorlib adı verdiğimiz .Net platformunun exe'lerini çalıştırmakla yükümlü olan dll tarafından üretilen 128 bytelik bir değerdir.Bu değer Hash algoritması ile 20 bytelik bir değere çevirilir ve bu 20 bytelik değerin son 8 byte alınıp ters çevirilerek public key bilgisi oluşturulur.Bu da benzersiz bir assembly ortaya çıkarır.Daha sonra Visual Studio Command Prompt yardımıyla sn.exe aracı kullanılarak key değeri oluşturulur.

sn –k MyKey.snk

Datalar binary olarak tutulduğundan dolayı uzantının bir önemi yoktur.İstediğimiz değeri verebiliriz. Ancak Windows tarafından tanınan uzantı .snk’ dır ve kullanılması tavsiye edilir.Bir sonraki aşamada oluşturulan .snk uzantılı dosya ile GAC’a atılacak olan dll dosyası derlenir.

csc /t:library /KeyFile:MyKey.snk Derlenecekolan.dll

Bu işlemde sonra artık assembly’i GAC’a atabiliriz.Bu işlem için gacutil.exe aracı kullanılmalıdır.

gacutil –i Derlenecekolan.dll

Artik assembly GAC’a atılmıştır.Bu adımdan sonra yapılması gereken bu dll referans edecek olan uygulama kendi klasörü altında bulunan dll ile tekrar derlenmelidir.Derleme işlemi sonucunda artık aynı klasör altında bulunan dll silinse dahi uygulama sorunsuz olarak çalışacaktır.Çünkü dllimizi kullanan uygulama artık GAC’da duran dll'i referans olarak kullanmaktadır.Bu dll sadece kullanıldığı zaman belleğe çıkmaktadır.