C#nedir?com
 
YAZAR HAKKINDA
Umut Ozkan
Umut Ozkan
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
2 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: anahtar application assembly dinamik farkli foreach hakkinda main(string[] metodu metotlari private public sinifi static tipinin C# / VC#/.NET Umut Ozkan
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : C# / VC#/.NET
Yayınlanma Tarihi : 3.8.2007
Okunma Sayısı : 32805
Yorum Sayısı : 10     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
XML - Deniz Kılınç
emre TAŞ
yazının devamı >
emre TAŞ
Decompiling and Reverse Engineering .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Masaüstü mü ? İnternet Mi? .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
.Net Kavramları - .Net Radyo
emre TAŞ
yazının devamı >
emre TAŞ
Yeni Başlayanlar için - .Net Radyo
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 10.8.2020
Turhal Temizer
Mac OS/X Removing CUDA 10.8.2020
Burak Selim Şenyurt
Sekiz Saatlik Sonsuz Döngü 10.8.2020
Burak Selim Şenyurt
Switch Case Kullanmadan Kod Yazılabilir mi? 10.8.2020
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Etkili Reflection(Yansıma) Teknikleri
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
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.

Show_metaData

showingMetadata2
   //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.

uyari Yansıma teknikleri, Eklenti (plug-in) ve Nitelik (attribute) tabanlı uygulamalarda sıklıkla kullanılı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.

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();
        }
    }
}
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.

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();
}
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.

Şimdi de kendi yazdığımız bir tip üzerinden gidelim.

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
        }
    }
}
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).

Diğer bir Type nesne örneğini oluşturma yöntemi ise "typeof" operatörüdür.

//typeof operatörüde geriye bir Type nesne örneği döndürür.
Type tip5 = typeof(Garaj.Araba);
Console.WriteLine(tip5);
Uygulamamızı çalıştırdığımızda aşağıdaki ekran görüntüsünü alırız.

cmdOut1

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.

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.
}
//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.

Benzer şekilde alan (field) ve özellikleride (property) elde edelim.

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);
}
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 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);
}
Şimdi de metotlarımızı kullanacak olan, uygulamanın başlangıç noktası Main metodunu yazalım.

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);
        }
    }
}

cmdout2
//Uygulamanın çalıştıktan sonraki ekran çıktısı
uyari * 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)
Ş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.

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.

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");
        }
    }
}
Ş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;
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();
        }
    }
}
Programın ekran çıktısı aşağıdaki gibidir.

CmdOut3

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();
}
cmdout4
//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.

uyari
//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);
Ş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.

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);
    }
}
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.

cmdout5

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);
}
cmdout6

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));
    }
}
cmdout7
//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.

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();
        }
    }
}

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.

exception

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.

vsout

Güncellemelerden sonra uygulamamızı tekrar çalıştıralım.

cmdout8

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
umut.ozkan@netron.com.tr Ornek için tıklayın
Makale:
Etkili Reflection(Yansıma) Teknikleri C#, Visual C# ve .NET Umut Ozkan
  • Yazılan Yorumlar
  • Yorum Yaz
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
MAR
25
2016
Çok iyi bir makale. Elinize sağlık.
EYL
14
2009
güzel bir çalışma olmuş
ARA
4
2007
reflection konusunda ayrintili ve yararli bir makale olmus. elinize saglik. tesekkürler.
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • 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