Asembly Nedir?
Hemen ilk başta belirtelim ki bu makalede bahsedeceğimiz Assembly'nin alt seviye bir programlama dili olan Assembly ile yakından uzaktan hiçbir alakası yoktur. Sadece bir isim benzerliği vardır. .NET platformunda yazdığımız kodlar sonucunda oluşturduğumuz bütün .exe uzantılı dosyalara ve .dll uzantılı dosyalara genel olarak Assembly denilmektedir. Projemize ait derlenmiş kodlar ve metadata dediğimiz bir takım özniteleyici kodlar Assembly'ler içerisinde bulunur. Assembly'lerin kabaca özellikleri aşağıdaki gibi sıralanabilir.
1-) Assembly'lerde metadata denilen veriler, Assembly'deki tür bilgileri ve başka kaynaklarla olan bağlantılar saklanır.
2-) Assembly'de(dll yada exe) kendilerine ait versiyon bilgisi tutulur. Hatırlarsanız klasik dll ve exe tipi dosyalarda versiyon bilgisi saklanmadığı için çeşitli uyumsuzluklar yaşanabilmekteydi. Mesela farklı iki firmanın hazırladığı dll 'ler aynı isimli olduğunda sonradan register edilen dll halihazırda bulunan dll 'in üzerinde yazıldığı için sistemde bulunan bazı uygulamalarda sorun çıkıyordu. Dll 'ler bu tür sorunlara yol açtığı için DLL Hell (Dll cehennemi) kavramı ortaya çıkmıştı. Aslında COM dll 'leri ile bu sorun bir nebze ortadan kalkmışsa da asıl çözüm Assembly'ler ile gelmiştir.
3-) Assembly'lerde versiyon bilgisi saklandığı için bir uygulama içerisinde farklı versiyonlara sahip Assembly'leri kullanabiliriz.
4-) Program kurma işlemi, Assembly 'ye ilişkin dosyayı direkt kopyalayarak yapılabilir. Eski sistemde DLL 'lerin register edilmesi gerekiyordu.
Assembly'lerin en önemli özelliklerinden birisi de Application Domain dediğimiz kavramdır. Application Domain sayesinde bir proses içinde birden fazla birbirinden bağımsız çalışan Assembly 'yi çalıştırma imkanına kavuşuruz. Bu konuya açıklayıcı bir örnek olması açısından aşağıdaki örneği inceleyebilirsiniz.
Bu örnekte iki tane Console uygulaması yapacağız. Bu iki uygulamaya ait çalışır durumdaki dosyalara artık Assembly diyebilirsiniz. Aşağıdaki ilk örnekte Main işlevi içerisinde ekrana bir yazı yazdırıyoruz.
//assembly1.cs using System; namespace assembly1 { class csnedir1 { static void Main(string[] args) { Console.WriteLine("Beni disardan yüklediler."); } } } |
//assembly2.cs using System; namespace assembly2 { class csnedir2 { static void Main(string[] args) { AppDomain apd2 = AppDomain.CreateDomain("Csnedir"); apd2.ExecuteAssembly("assembly1.exe"); } } } |
Assembly hakkında bu geniş giriş bilgisini verdikten sonra Assembly'nin fiziksel yapısından bahsedelim biraz. Bir Assembly belgesinde Assembly metadata, tür(type) metadata, kaynaklar ve IL(Intermadiate Language) kodu bulunur. Bütün bu yapılar bir Assembly dosyasında bulunabileceği gibi Assembly metadata'lar sayesinde dışarıdaki kaynaklara referans da verilebilir. Assembly'lerin en önemli yapısı Manifest dediğimiz parçasıdır. Manifest assembly metadata'lar bulunur. Peki nedir bu Assembly metadata'lar? Bir Asembly adı, versiyonu gibi kimlik bilgileri, ilgili Assembly ile ilgili olan diğer dosyalar, başka Assembly'lere olan referanslar gibi bilgilerin tamamına Assembly metadata denir. İşte bu bilgilerin oluşturduğu kümeye Manifest denilmektedir. Assembly'lerin Manifest bölümünde bulunan elemanlar temel olarak aşağıdaki tabloda verilmiştir.
Özellik | Anlamı |
AssemblyCompany | Assembly'nin firma bilgisi |
AssemblyCopyright | Copyright bilgisi |
AssemblyCulture | İlgili Assembly'ye ait kültür bilgisi(Almanya,İngiltere,Türkiye vs..) |
AssemblyDelaySign | Gecikmeli imzanın olup olmayacağı (True ya da False) |
AssemblyDescription | Assembly ile ilgili kısa açıklama |
AssemblyFileVersion | Win32 sistemindeki dosya versiyonu |
AssemblyInformationalVersion | CLR tarafından kullanılmayan ve okunabilirliği yüksek olan versiyon bilgisi |
AssemblyKeyFile | Assembly'nin kayıt edilmesi için gereken anahtarın bulunduğu dosya |
AssemblyKeyName | Kayıt için gereken anahtar sözcük |
AssemblyProduct | Ürün adı |
AssemblyTitle | Assembly'nin adı |
AssemblyTrademark | Trademark bilgisi |
AssemblyVersion | String şeklindeki Version numarası |
Assembly'ler private ve shared olmak üzere ikiye ayrılır. Bunları detaylı olarak açıklamaya başlamadan önce Assembly'leri görüntülemek için kullanılan ILDASM.exe aracını inceleyelim. ILDASM.exe MSIL kodu içeren assembly dosyalarını okur ve kullanışlı bir arayüz ile kullanıcıya sunar. ILDASM.exe programını çalıştırmak için komut satırına ILDASM.exe yazmamız yeterlidir. Açılacak pencereden File->Open menüsünü kullanarak görüntülemek istediğiniz Assembly dosyasını seçin.(Aşağıda gördüğünüz ekran görüntüleri Assembly2.exe'nin görüntüleridir.) Bir assembly'deki türler, sınıflar, fonksiyonlar çeşitli sembollerle temsil edilmiştir. Hangi sembollerin ne anlama geldiğini MSDN kitaplığından bulabilirsiniz.
Şimdi de açılacak pencereden Main bölümüne tıklayın, ve aşağıdaki görüntüyü elde edin. Buradaki bütün kodlar IL kodudur.
Diğer bölümlerde tıklayarak IL kodlarını inceleyebilirsiniz.
Yukarıda bahsettiğimiz gibi Assembly'ler private ve shared olmak üzere ikiye ayrılır. Normal olarak geliştirilen Assembly'ler private Assembly olarak adlandırılır. Bu tür assembly'ler uygulama ile aynı dizinde ya da alt dizinlerde bulunur. Versiyon ve isim uyuşmazlığı sorunu bu tür assembly'lerde olmamaktadır. Shared assembly'ler ise daha çok büyük projelerde mesela bir projenin bir firmaya ait farklı ofislerinde gerçekleştirildiği durumlarda kullanılır. Bu durumda assembly'lerin uyması gereken bazı kurallar vardır. Bunlardan en önemlisi strong name dediğimiz tekil bir isme sahip olmasıdır. Bu sayede shared assembly'ler tekil olduğu için bir sistemde global düzeyde işlem görürler. Yani farklı farklı uygulamalardan aynı anda shared assembly'lere ulaşılabilir. Şimdi shared assembly kavramını biraz açalım.
Shared Assembly
Assembly'ler varsayılan olarak private'tır. Bu yüzden bu tür Assembly'ler sadece bulundukları dizin içerisindeki uygulamalar tarafından görülür ve çalıştırılırlar. Oysa ki bazı durumlarda bütün programlar tarafından o Assembly'ye birbirlerinden bağımsız olarak erişilmesini isteriz. Bunu sağlamak için Global Assembly Cache denilen bir sistemden faydalanacağız. .NET 'in yüklü olduğu bütün sistemlerde Assembly Cache mekanizması vardır. Bu Assembly Cache'ye yüklü olan Assembly'ler bütün uygulamalar tarafından kullanılabilir. Bir assembly'yi GAC'a(Global Assembly Cache) yüklemek için 3 yöntem kullanılır:
- Assembly'leri Windows Installer 2.0 ile yüklemek
- Gacutil.exe isimli .NET ile gelen aracı kullanmak
-
Şimdi adım adım bir shared assembly oluşturmayı görelim. Bunun için ikinci yöntemi kullanacağım. Başlangıç olarak gacutil.exe programı hakkında bilgi vermek istiyorum. Gacutil(global assembly cache utility) programı .NET ile birlikte gelir. Assembly cache'ye yeni assembly yüklemek varolan assembly'leri listelemek ve silmek için kullanılır. Komut satırından aşağıdaki parametrelerle bu programı çalıştırabiliriz.
* gacutil /l ---> GAC 'da bulunan bütün assembly'leri listeler.
* gacutil /i assemblydll---> assemblydll adlı shared assembly'yi GAC 'a yükler.
* gacutil /u assemblydll---> assemblydll adlı shared assembly GAC 'dan siler.
İlk adım olarak bütün shared assembly'lere strong name dediğimiz bir isim vermeliyiz. GAC 'da bulunan bütün assembly'lerin farklı bir adı vardır. COM teknolojisindeki globally unique identifier(GUID) 'e benzetebiliriz bu isimleri. Peki bu strong name 'leri nasıl oluşturacağız? Bu iş için yine .NET ile birlikte gelen sn.exe adlı aracı kullanacağız. sn programı aşağıdaki gibi kullanılarak bir tekil isim oluşturulur ve anahtar.snk adlı dosyaya yazılır.
sn -k anahtar.snk
anahtar.snk dosyasını oluşturduktan sonra bu anahtar ismi projemizdeki AssemblyInfo.cs dosyasındaki manifeset bölümüne ekliyoruz. Yani AssemblyKeyFile özelliğini anahtar.snk olarak değiştiriyoruz. Sonuç olarak AssemblyInfo.cs dosyası aşağıdaki gibi olacaktır.
...............
[assembly AssemblyDelaySign(false)]
[assembly AssemblyKeyFile("../../anahtar.snk")]
[assembly AssemblyKeyName("")]
...............
Bu işlemleri yaptıktan sonra projeyi "Build" edip oluşan Assembly dosyasını gacutil.exe yardımıyla GAC 'a ekliyoruz. Bu işlemi komut satırından aşağıdaki gibi yapmalıyız.
gacutil /i Assembly1.dll
Bu işlemi yaptıktan sonra shared olan bu assembly'ye istediğimiz .NET projesinden ulaşabiliriz. Tabiproject->Add reference menüsünden shared assembly'ye referans verdikten sonra yapabiliriz bunu. Shared assembly olduğu için yeni bir projede bu assembly kullandığımız da lokal bir kopyası oluşturulmaz dolayısıyla GAC üzerinden erişilir. http://www.csharpnedir.com/articles/read/?id=58
Hiç yorum yok:
Yorum Gönder