| 
      
        |  SİTE 
            İÇİ ARAMA |  
        |  |  
      
        |  Blogroll |  
        |  |    | 
        
            |  |  
            | 
                    
                        | Etkili Reflection(Yansıma) Teknikleri |  |  
                        | 
	
    
		
            | Gönderiliyor lütfen bekleyin... | 
 |  |  
            | Visual Studio uygulama geliştirme ortamının (IDE) belkide en güçlü özelliği otomatik kod tamamlayıcı’dır(intellisense). 
Visual Studio bu güçlü özelliği, assembly (*.dll,*.exe) üzerindeki metadata bilgisinden faydalanarak bize sunmaktadır. Metadata’dan kısaca bahsetmek gerekirse; üzerinde bulunduğu assembly’nin  tüm üyeleri (sınıfları (class),yapıları (struct),metotları (method),özellikleri (property),alanları (field)...) hakkında açıklamalar tutan bileşen olduğu söylenebilir. Başlamadan önce herhangi bir assembly üzerindeki metadata bilgisine ildasm aracı ile gözatalım. 
 
  
 
   //ildasm aracı ile metadata bilgilerinin görüntülenmesi
 
 Şekildede görüldüğü gibi assembly üzerinde, assembly ve üyeleri hakkında bilgiler tutulmaktadır (metadata). Metadata bilgileri sizin de tahmin edebileceğiniz gibi sadece uygulama geliştirme ortamı (IDE) tarafından kullanılmazlar. Bizde çalışma zamanında (runtime) assembly(*.dll,*.exe) içindeki üyeler hakkında bilgi edinmek isteyebiliriz.Bu bilgilerin elde edileceği yer metadata,metadata’nın okunmasında kullanılan bu tekniklerin tümü yansıma teknikleri olarak isimlendirilir.Yansıma tekniklerini kullanacağımız ilgili üyeler 
	System.Reflection isim alanında yer almaktadır.
 
 
 
      System.Reflection isim alanında ki üyeleri incelemeye geçmeden önce 
	System.Type sınıfını incelememiz faydalı olacaktır.System.Type sınıfı yapısında, assembly’ler içindeki üyeler hakkında bilgi edinmemizi sağlayan birtakım metotlar ve özellikler (property) barındırır. System.Type sınıfı soyut (abstract) bir sınıf olduğu için, new anahtar sözcüğü ile oluşturulamaz.Bu yüzden nesne örneğini oluşturabilmek için object sınıfının GetType() metodundan faydalanabiliriz.Her .Net tipi object’den türediği için dolayısı ile GetType() metodu her .Net tipinde yeralır.Dilerseniz şimdi de kod tarafında bakalım.
        |  | Yansıma teknikleri, Eklenti (plug-in) ve Nitelik (attribute) tabanlı uygulamalarda sıklıkla kullanılır. |  
 
 
      Görüldüğü gibi Type sınıfının nesne örneğini new anahtar sözcüğü ile oluşturamadık.Ancak istenen tipin GetType() metodu yardımıyla Type sınıfından bir nesne örneği oluşturabildik. 
	Dilerseniz Type sınıfının nesne örneğini, sınıfın static metotlarından biri olan GetType() metoduylada oluşturabilirsiniz.
        | using System; using System.Collections.Generic;
 using System.Text;
 namespace FirstProjectReflection
 {
 class Program
 {
 static void Main(string[] args)
 {
 int tamSayi = 
		10;
 /*DERLEYİCİ 
		HATASI:
 * Error 1 
		Cannot create an instance of the abstract class or interface 
		’System.Type’ 
		D:\Work\testing\Reflactions\FirstProjectReflection\Program.cs 12 24                 
		FirstProjectReflection
 * Type tip = 
		new Type();
 */
 Type tip = 
		tamSayi.GetType();
 Console.WriteLine(tip.ToString());
 Console.ReadLine();
 }
 }
 }
 |  
 
 
      Type.GetType() metodunun üç ayrı aşırı yüklenmiş versiyonu bulunmaktadır.Metot parametrelerinden birisi bool tipindeki 
	throwOnError eğer string olarak belirtilen tip bulunamaz ise exception fırlatılıp fırlatılmayacağını, diğer bir parametre olan bool tipindeki 
	ignoreCase ise string olarak yazılan isimalanı.tip teki büyük küçük harf duyarlılığını belirlemek için kullanılır.
        | static void Main(string[] args) {
 int tamSayi = 10;
 /*ERLEYİCİ HATASI:
 * Error 1 Cannot create an instance of the abstract class or 
		interface ’System.Type’ 
		D:\Work\testing\Reflactions\FirstProjectReflection\Program.cs 12 24 
		FirstProjectReflection
 * Type tip = new Type();
 */
 Type tip = tamSayi.GetType();
 Console.WriteLine(tip.ToString());
 Type tip2 = Type.GetType("System.Int32");
 Console.WriteLine(tip2);
 Console.ReadLine();
 }
 |  
 Şimdi de kendi yazdığımız bir tip üzerinden gidelim.
 
 
 
      Aynı program.cs dosyasına (farklı bir .cs dosyasındada tasarlanabilirdi) bir isim alanı (namespace) ve bu isim alanı altına Araba isimli sınıfımızı (class) oluşturduk.Araba sınıfı içerisine ise iç tip (nesned) olarak bir numaralandırıcı (enumaration) oluşturduk. Uygulamanın giriş noktası olan isim alanı ve sınıfda ki Main metodundan ise farklı bir namespace deki sınıfa ulaşıp Type tipinde bir nesne örneği oluşturduk (tip3).İç tip (nesned) olarak tasarlanan numaralandırıcıya (enumaration) ise "+" işaretini kullanarak eriştik (tip4).
        | using System; using System.Collections.Generic;
 using System.Text;
 namespace FirstProjectReflection
 {
 class Program
 {
 static void Main(string[] args)
 {
 int tamSayi = 
		10;
 /*DERLEYİCİ 
		HATASI:
 * Error 1 
		Cannot create an instance of the abstract class or interface 
		’System.Type’ 
		D:\Work\testing\Reflactions\FirstProjectReflection\Program.cs 12 24 
		FirstProjectReflection
 * Type tip = 
		new Type();
 */
 Type tip = 
		tamSayi.GetType();
 Console.WriteLine(tip.ToString());
 Type tip2 = 
		Type.GetType("System.Int32");
 Console.WriteLine(tip2);
 
 //son 
		parametre true olduğu için garaj.araba da büyük küçük harf duyarlılığı 
		gözardı edildi.
 Type tip3 = 
		Type.GetType("garaj.araba", false, true);
 Console.WriteLine(tip3.ToString());
 //iç tip 
		(nesned) olarak belirlenen numaralandırıcıya (enumaration) erişmek için 
		+ işareti kullanılır.
 Type tip4= 
		Type.GetType("Garaj.Araba+RotBalans");
 Console.WriteLine(tip4);
 Console.ReadLine();
 }
 }
 }
 namespace Garaj
 {
 class Araba
 {
 enum RotBalans
 {
 SagOn,SolOn,SagArka,SolArka
 }
 }
 }
 |  
 Diğer bir Type  nesne örneğini oluşturma yöntemi ise "typeof" operatörüdür.
 
 
 
      Uygulamamızı çalıştırdığımızda aşağıdaki ekran görüntüsünü alırız.
        | //typeof operatörüde geriye bir Type nesne örneği döndürür. Type tip5 = typeof(Garaj.Araba);
 Console.WriteLine(tip5);
 |  
 
  
 Tiplerimiz hakkında biraz daha detaylı bilgi edinsek hiç de fena olmaz. Bunun için  kendi kişisel tip görüntüleyicimizi yazalım ve tip üyelerine biraz daha yakından bakalım. İlk etapda tip ’ in içerdiği metotlara göz atmak için (yansıma) "MetotlariListele" isimli metodumuzu kodlayalım.
 
 
 
      //MethodInfo sınıfını kullanabilmek için System.Reflection isim alanının using anahtar sözcüğüyle eklenmiş olması gerekir.
	Metodumuz parametre olarak Type tipinden bir nesne örneği alıyor.Bu parametre yansımasını almak istediğimiz tipi temsil etmektedir.Parametre olarak alınan Type nesne örneği üzerinden GetMethods() metodu geriye MethodInfo tipinde dizi döndürür.Tahmin edebileceğiniz gibi dizinin elemanları tip içinde bulunan metotlardır.
        | static void MetotlariListele(Type t) {
 //GetMethods metodu ile verilen tip içerisindeki tüm 
		metotları elde ederiz.Geriye System.Reflection.MethodInfo tipinde bir 
		dizi döndürür.
 MethodInfo[] metotlar = t.GetMethods();
 Console.WriteLine("*******{0} tipinin 
		metotları********",t.ToString());
 foreach (MethodInfo mInfo in metotlar)
 {
 Console.WriteLine(mInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);// Enviroment.NewLine 
		\n ile aynı işi yapar.
 }
 |  
 Benzer şekilde alan (field) ve özellikleride (property) elde edelim.
 
 
 
      Ek olarak Type nesne örneği üzerinden erişebildiğimiz birtakım özelliklerede gözatmak için "DurumListele" metodunuda aşağıdaki şekilde kodlayalım.
        | static void AlanlariListele(Type t) {
 FieldInfo[] alanlar = t.GetFields();
 Console.WriteLine("*******{0} tipinin alanları********", 
		t.ToString());
 foreach (FieldInfo fInfo in alanlar)
 {
 Console.WriteLine(fInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);
 }
 static void OzellikleriListele(Type t)
 {
 PropertyInfo[] ozellikler = t.GetProperties();
 Console.WriteLine("*******{0} tipinin özellikleri********", 
		t.ToString());
 foreach (PropertyInfo pInfo in ozellikler)
 {
 Console.WriteLine(pInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);
 }
 |  
 
 
      Şimdi de metotlarımızı kullanacak olan, uygulamanın başlangıç noktası  Main metodunu yazalım.
        | static void DurumListele(Type t) {
 Console.WriteLine("*******{0} tipinin durumu********", 
		t.ToString());
 Console.WriteLine("Tip Soyut mu : {0}",t.IsAbstract);
 Console.WriteLine("Tip Generic mi : {0}", t.IsGenericType);
 Console.WriteLine("Tip Arayüz mü : {0}", t.IsInterface);
 Console.WriteLine(Environment.NewLine);
 }
 |  
 
 
      
        | using System; using System.Collections.Generic;
 using System.Text;
 using System.Reflection;//dikkat
 namespace KisiselTipGoruntuleyici
 {
 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine("İncelemek istenen tipi giriniz (Isimalani.Tip)");
 string 
		tipAdi=string.Empty;
 try
 {
 tipAdi = Console.ReadLine();
 Type t = Type.GetType(tipAdi, true);
 MetotlariListele(t);
 AlanlariListele(t);
 OzellikleriListele(t);
 DurumListele(t);
 }
 catch 
		(TypeLoadException)
 {
 Console.WriteLine("HATA OLUŞTU : belirtilen tip bulunamadı");
 }
 catch 
		(Exception ex)
 {
 Console.WriteLine(ex.Message);
 }
 Console.ReadLine();
 }
 static void MetotlariListele(Type t)
 {
 //GetMethods 
		metodu ile verilen tip içerisindeki tüm metotları elde ederiz.Geriye 
		System.Reflection.MethodInfo tipinde bir dizi döndürür.
 MethodInfo[] 
		metotlar = t.GetMethods();
 Console.WriteLine("*******{0} tipinin metotları********",t.ToString());
 foreach 
		(MethodInfo mInfo in metotlar)
 {
 Console.WriteLine(mInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);// Enviroment.NewLine \n ile aynı 
		işi yapar.
 }
 static void AlanlariListele(Type t)
 {
 
 FieldInfo[] 
		alanlar = t.GetFields();
 Console.WriteLine("*******{0} tipinin alanları********", t.ToString());
 foreach 
		(FieldInfo fInfo in alanlar)
 {
 Console.WriteLine(fInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);
 }
 static void OzellikleriListele(Type 
		t)
 {
 PropertyInfo[] ozellikler = t.GetProperties();
 Console.WriteLine("*******{0} tipinin özellikleri********", 
		t.ToString());
 foreach 
		(PropertyInfo pInfo in ozellikler)
 {
 Console.WriteLine(pInfo.Name);
 }
 Console.WriteLine(Environment.NewLine);
 }
 static void DurumListele(Type t)
 {
 Console.WriteLine("*******{0} tipinin durumu********", t.ToString());
 Console.WriteLine("Tip Soyut mu : {0}", t.IsAbstract);
 Console.WriteLine("Tip Generic mi : {0}", t.IsGenericType);
 Console.WriteLine("Tip Arayüz mü : {0}", t.IsInterface);
 Console.WriteLine(Environment.NewLine);
 }
 }
 }
 |  
  //Uygulamanın çalıştıktan sonraki ekran çıktısı
 
 
      Şuana dek Type sınıfı üzerinde tiplerle nasıl çalışabileceğimizi incelemeye çalıştık. Şimdide dinamik olarak assembly’leri (*.dll,*.exe) nasıl kullanabileceğimizi incelemeye çalışalım.
        |  | * MethodInfo nesne örneği üzerinden metotların geri dönüş tipleri,parametreleri elde edilebilir ve hatta istenen metotlar çağırılabilir. 
 *PropertyInfo nesne örnekleri üzerinden özelliğin değeri atanıp (set),istenebilir (get)
 |  
 System.Reflection.Assembly sınıfı assembly dosyalarını dinamik olarak kullanabilmemize olanak sağlar.Assembly sınıfınında yapıcı metotları (constructior) private olarak belirlendiği için, "new" anahtar sözcüğü ile belleğe çıkarılamaz.Assembly nesne örneğini oluşturmak için yine Assembly sınıfının statik Load,LoadFrom,LoadFile metotları kullanılmaktadır.
 
 İşe dinamik olarak kullanacağımız assembly dosyasını oluşturmakla başlayalım.Bunun için yeni bir class library dosyası açalım ve kullanacağımız sınıfımızı yazalım.
 
 
 
      Şimdide bu sınıfı dinamik olarak kullanacak (yansıtacak) sınıfımızı oluşturalım.Ama önce Araba sınıfını derlediğimizde oluşan Garaj.dll dosyasını yeni açtığımız projeye referans olarak ekleyelim.
        | using System; using System.Collections.Generic;
 using System.Text;
 namespace Garaj
 {
 public class Araba
 {
 //Guid (global unique identifier) 128 
		bitlik benzersiz bir anahtar değerini üzerinde taşıyabilen bir sınıftır.
 private Guid _saseNo;
 private string _marka;
 public Araba()
 {
 _saseNo = 
		Guid.NewGuid();
 }
 public Araba(string marka)
 {
 Marka = 
		marka;
 //Guid.NewGuid() yeni bir anahtar oluşturur.
 _saseNo = 
		Guid.NewGuid();
 }
 public Guid SaseNo
 {
 //saşe 
		numarasının değiştirilmemesini istediğimiz için sadece get bloğu 
		oluşturduk.
 get { return 
		_saseNo; }
 }
 
 public string Marka
 {
 get { return 
		_marka; }
 set { _marka 
		= value; }
 }
 public void Hizlan()
 {
 Console.WriteLine("Hızlanılıyor...");
 }
 public void Dur()
 {
 Console.WriteLine("Durduruldu");
 }
 }
 }
 |  
 
 
      Programın ekran çıktısı aşağıdaki gibidir.
        | using System; using System.Collections.Generic;
 using System.Text;
 using System.Reflection;
 namespace AssemblySinifi
 {
 class Program
 {
 static void Main(string[] args)
 {
 Assembly 
		asmbl = null;
 try
 {
 Console.WriteLine("***Yükleme Başlatıldı***\n");
 asmbl = Assembly.Load("Garaj");
 Console.WriteLine("***Yükleme Başarılı***\n");
 Console.WriteLine("***Assembly Tam Adı***\n{0}\n", asmbl.ToString());
 Console.WriteLine("***Okunan yer***\n{0}\n", asmbl.Location);
 Console.WriteLine("***Okunan Assembly GAC’dan mı okunuyor?***\n{0}\n", 
		asmbl.GlobalAssemblyCache);
 }
 catch 
		(Exception ex)
 {
 Console.WriteLine("Hata Oluştu : {0}",ex.Message);
 }
 Console.ReadLine();
 }
 }
 }
 |  
 
   
 Assembly.Load metodu, referans olarak eklenmiş assembly dosyalarının dinamik olarak kullanılmasına olanak sağlar.Referans olarak eklenmemiş, belirli bir dizin altındaki assembly (*.dll,*.exe) dosyalarını ise Assembly.LoadFile veya LoadFrom metotları ile kullanabiliriz.
 
 
 
      
        | static void Main(string[] args) {
 Assembly asmbl = null;
 //sizin ilgili dizininiz için belirtilen yolu değiştirmeniz 
		gerekebilir.
 string 
		frameWorkKlasor="C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\";
 
 try
 {
 Console.WriteLine("***Yükleme 
		Başlatıldı***\n");
 asmbl = 
		Assembly.LoadFrom(frameWorkKlasor + "System.dll");
 Console.WriteLine("***Yükleme 
		Başarılı***\n");
 Console.WriteLine("***Assembly Tam 
		Adı***\n{0}\n", asmbl.ToString());
 Console.WriteLine("***Okunan 
		yer***\n{0}\n", asmbl.Location);
 Console.WriteLine("***Okunan Assembly 
		GAC’dan mı okunuyor?***\n{0}\n", asmbl.GlobalAssemblyCache);
 }
 catch (Exception ex)
 {
 Console.WriteLine("Hata Oluştu : 
		{0}", ex.Message);
 }
 Console.ReadLine();
 }
 |   //Uygulamanın Ekran Çıktısı
 
 Ekran çıktısında dikkatimizi çekmesi gereken bölümler, "Okunan Yer" ve "Okunan Assembly GAC’dan mı okunuyor?" bölümleridir.Okunan assembly dosyası GAC’dan okunduğu için GlobalAssemblyCache özelliği (property) geriye true değer döndürmüştür. Diğer dikkat edilmesi gereken nokta ise  LoadFrom metoduna parametre olarak ("C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\System.dll") verilen dosya yoluyla,"Okunan Yer" bölümünde ki (Assembly sınıfının nesne örneği üzerinden erişilen Location özelliği) dosya yolunun birbirinden farklı oluşudur.Bunun sebebi GAC (C:\WINDOWS\assembly) daki klasör yapısının farklı oluşudur.Bu konuya bu makalede değinilmeyecektir.
 
 
 
      Şimdi ise Class library projesi olarak hazırladığımız Garaj.dll içindeki üyeleri inceleyelim. Program.cs dosyamızda ki ilgili eklentiler aşağıdaki gibidir.
        |  | //GAC’dan Assembly yüklemenin diğer bir yolu ise; 
			Assembly globalAsm = Assembly.Load(@"System.Data, Version=1.0.5000.0, PublicKeyToken=b77a5c561934e089, Culture=’Neutral’");
 Console.WriteLine(globalAsm.GlobalAssemblyCache);
 |  
 
 
      Burda yine type sınıfını incelerken yaptığımız işlemlerle benzer işlemler yaptık.Assembly sınıfı nesne örneği üzerinden eriştiğimiz GetTypes metodu sayesinde Araba sınıfı alan (field) ve özellikleri (property) hakkında bilgiler edindik.Uygulamanın ekran çıktısı aşağıdaki gibidir.
        | Console.WriteLine("***Yüklenen 
		Assembly Üyeleri Hakkında Bilgi Edinmek***"); Assembly asmblGaraj = Assembly.Load("Garaj");
 Type[] tipler = asmblGaraj.GetTypes();
 foreach (Type tip in tipler)
 {
 PropertyInfo[] ozellikler= tip.GetProperties();
 foreach (PropertyInfo ozellik in ozellikler)
 {
 Console.WriteLine("{0} tipinin 
		ozellikleri {1}",tip.FullName,ozellik.Name);
 }
 FieldInfo[] alanlar = tip.GetFields();
 foreach (FieldInfo alan in alanlar)
 {
 Console.WriteLine("{0} tipinin 
		alanları {1}", tip.FullName, alan.Name);
 }
 }
 |  
 
   
 Fakat görüldüğü gibi  sınıfın özelliklerine erişebilirken, private field’larına erişemedik.Sınıfın private erişim belirleyicilerine sahip üyelerine erişebilmek için BindingFlags numaralandırıcısından faydalanmalıyız. Gerekli güncellemelerden sonra kodumuz aşağıdaki gibi görünmelidir.
 
 
 
      
        | FieldInfo[] alanlar = tip.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo alan in alanlar)
 {
 Console.WriteLine("{0} tipinin alanları {1}", tip.FullName, alan.Name);
 }
 |    
 Başka bir sınıftan diğer bir sınıftaki private üyelere erişimi yansıma (reflection) ile mümkün kıldık.Peki bu üyelere değer verip,alabilirmiyiz ? Şimdide bu konuyu incelemeye çalışalım.
 
 
 
      
        | FieldInfo[] alanlar = tip.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo alan in alanlar)
 {
 Console.WriteLine("{0} tipinin alanları {1}", tip.FullName, alan.Name);
 if (alan.Name == "_saseNo")
 {
 Console.WriteLine("\n***Private SaseNo değerinin değiştirilmesi***\n");
 
 //GetValue ve SetValue metotları parametre olarak Get ve Set edilecek Field’ın bulunduğu sınıfı alır.Bu yüzden Assembly nesne örneği üzerinden CreateInstance metodu ile sınıfın nesne örneği oluşturulur.
 
 Garaj.Araba ornAraba = (Garaj.Araba)asmblGaraj.CreateInstance("Garaj.Araba");
 Console.WriteLine("{0} şimdiki değeri {1}", alan.Name, alan.GetValue(ornAraba));
 Console.WriteLine("Değer değiştiriliyor");
 alan.SetValue(ornAraba, Guid.NewGuid());
 Console.WriteLine("{0} şimdiki değeri {1}\n",alan.Name,alan.GetValue(ornAraba));
 }
 }
 |   //Yapılan güncellemelerden sonra uygulamanın ekran çıktısı
 
 BindingFlags numaralandırıcısı sayesinde, farklı bir sınıf içerisinden, diğer bir sınıf içerisindeki private erişim belirleyicili bir üyeye eriştik ve değerini değiştirdik.
 
 Application Domain Kavramı
 
 Application Domain, işletim sistemi üzerinde çalışan programlar arasında bellek anlaşmazlıklarından doğacak sorunlara çözüm olarak, bu programlar arasında izolasyon sağlar.Her uygulama kendine has bir AppDomain ( Application Domain ) üzerinde çalışır.AppDomain  kavramına bu makalede değinmemizin sebebi Assembly sınıfının Unload gibi bir metodunun olmayışından kaynaklanmaktadır.Konuyu biraz daha açmak gerekirse; Assembly.Load(),LoadFrom(),LoadFile() metotlarıyla yüklediğimiz assembly dosyaları, mevcut çalışan uygulamanın AppDomainine yüklenir ve yüklediğimiz bu assembly’i bellekten kaldırma olanağımız yoktur.İşte bu noktada AppDomain sınıfını kullanarak dinamik olarak yüklediğimiz assembly dosyasını, farklı bir application domain altında oluşturarak  kontrol altına almış oluruz. AppDomain sınıfı yeni application domainler oluşturmamıza, oluşturduğumuz application domain hakkında bilgiler edinmemize ve (üzerinde çalışan assemblyler ile birlikte) bellekten silmemize olanak sağlar.
 
 Nasıl yeni application domainler oluşturacağımıza ve dinamik olarak oluşturduğumuz assembly’leri nasıl bu application domaine dahil edeceğimizi inceleyelim.
 
 
 
      Tasarladığımız Garaj.dll’i projeye referans olarak ekledikten sonra System.AppDomain (yapıcı metotları private olduğu için new anahtar sözcüğü ile oluşturamadık) sınıfı ile yeni bir application domain oluşturduk.Oluşturduğumuz application domaine dinamik olarak Garaj.Araba assembly dosyasını yükledikten sonra AppDomain.Unload() metodu ile yeni oluşturduğumuz application domaini bellekten düşürdük ve Try-Catch bloklarında yeni oluşturduğumuz application domaine yüklenen assembly’e erişmeye çalıştık. Uygulamayı çalıştırdığımızda aşağıdaki gibi bir çalışma zamanı hatası (exception) alırız.
        | using System; using System.Collections.Generic;
 using System.Text;
 using System.Reflection;
 namespace WhatisAppDomain
 {
 class Program
 {
 static void Main(string[] args)
 {
 //her program bir appdomainde calısır.programların izolesi icindir.assmbly load metodu ile bellege cıkardıklarımızı ne yazıkki unload gibi bir metot olmadıgı icin dusuremioruz.bu yuzden load edilenleri farklı app domainlere yuklemeliyiz.
 
 //suanki app domaini verir.
 Console.WriteLine( AppDomain.CurrentDomain.FriendlyName);
 
 //constructiorları private oldugu icin...
 //AppDomain nesne örneği bu şekilde oluşturulmalıdır.
 AppDomain app = AppDomain.CreateDomain("yeniEvsahibi");
 
 //assembly yeni appdomain  uzerine yuklendi.
 app.CreateInstanceFromAndUnwrap("Garaj.dll", "Garaj.Araba");
 
 //veya...
 //Activator.CreateInstanceFrom(
 //        app, "Car.dll", "UnderstandingActivatorClass.Car", false,
 //        BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance,
 //        null, new object[] { },
 //        null, null, null).Unwrap();
 
 //app domain dusuruldugunde assembly leri de gitti.erismeye calısalım.
 AppDomain.Unload(app);
 
 try
 {
 Assembly[] assms= app.GetAssemblies();
 foreach (Assembly aso in assms)
 {
 Console.WriteLine(aso.FullName);
 }
 }
 catch (Exception ex)
 {
 Console.WriteLine("HATA SEBEBİ : {0}",ex.Message);
 }
 Console.ReadLine();
 }
 }
 }
 
 
 |  
 
   
 Yeni oluşan application domain’e assembly serileştirilerek taşınacağı için, bizden ilgili assembly dosyasını [Serializable] niteliği (attribute) ile işaretlememizi ister.Tasarlardığımız Garaj.Araba sınıfına giderek güncellemeyi yapalım.
 
 
   
 Güncellemelerden sonra uygulamamızı tekrar çalıştıralım.
 
 
   
 Yeni oluşturduğumuz application domaine dinamik olarak yüklediğimiz assembly’e, yeni oluşturduğumuz application domaini bellekten düşürdükten sonra erişmeye çalıştığımız için ilgili hatayı aldık.Burda farklı bir application domaine yüklenen bir assembly’nin o application domain ile birlikte bellekten düştüğünü görmüş olduk.
 
 Yansıma (reflection) teknikleri uygulama geliştirme ortamının temel yapı taşlarını oluşturmaktadır.Ayrıca eklenti ve nitelik (attribute)  tabanlı uygulamalarda büyük önem taşımaktadır.
 
 Yansıma tekniklerini incelemeye çalıştığımız bu makalemizin sonuna gelirken sizlere bir daha ki makalede   buluşuncaya dek mutlu günler dilerim.
 
 Umut Özkan
 [email protected]
Ornek için tıklayın
 
                Makale:Etkili Reflection(Yansıma) Teknikleri C#, Visual C# ve .NET Umut Ozkan
 |  
            |  |  
            |  |  
            | 
                    
                        
                            
                        
                            Eklenen Son 10 
                            Bu Konuda Geçmiş 10 
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                            Son Eklenen 10 Makale Yükleniyor
                         
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         |  
            |  |  |