Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

C# Reflection

C# runtime’da tip bilgilerini elde edebilmemizi sağlayacak bir yapı sunmuştur ve buna reflection(yansıma) adı verilmiştir. Reflection sayesinde çok dinamik ve plug-in tabanlı uygulamalar geliştirmek imkansız olmaktan çıkmıştır. Kabaca reflectionı runtime da koda müdahale etmek olarak nitelendirebiliriz.
CLR(Common Language Runtime) içerisindeki kod bir assembly içerisine paketlenmiştir. Metadata CLR’ın kullandığı ve kodları execute ettiği ve bütün sınıf bilgilerini barındırdığı bir veridir.Bütün metod,property,event,delegate,enumaration’ların tip bilgileri metadata’da bulunur. Metadata parçalara ayrılmıştır.
Assembly Metadata : name,versiyon,strong name,culture gibi bilgiler bu parçada yer alır.

Type metadata : namespace ve class name’ler bu parçada bulunur.
Code (Intermediate Language Code) : Makine koduna çevrilmiş kod

Resources : string,image ve dosyalar gibi nesnelerdir.

 

//Mevcut çalışan kodun assembly’nin instance’ını yaratmak

Assembly asm = Assembly.GetExecutingAssembly();

String msg = String.Format(@”Full Name:{0},Location:{1},Only Reflection?:{2}”,

    asm.FullName,asm.Location,asm.ReflectionOnly);

MessageBox.Show(msg);

 

//Bu hata verir cunku Assembly’i sadece reclection için load ettik.

string fullName = “System.Transactions,Version 2.0.0.0,” +

    “Culture=neutral,PublicKeyToken=b77a5c561934e089”;

Assembly asm = Assembly.ReflectionOnlyLoad(fullName);

asm.CreateInstance(“System.Transactions.TransactionScope”);

 

//Her assembly en az bir modül içerir.

Assembly asm = Assembly.GetExecutingAssembly();

Module[] mods = asm.GetModules();

foreach (Module m in mods)

{

    Console.WriteLine(“Module Name:{0},n {1}”,m.Name,m.Assembly.FullName);

}

 

Properties altındaki AssemblyInfı sınıfı içerisinde assembly’nizin özelliklerini görebilirsiniz. Aşağıda bu sınıfa ait bazı attribute’ler listelenmiştir.
[
assembly: AssemblyTitle(“WindowsApp”)]

[assembly: AssemblyDescription(“”)]

[assembly: AssemblyConfiguration(“”)]

[assembly: AssemblyCompany(“”)]

[assembly: AssemblyProduct(“WindowsApp”)]

[assembly: AssemblyCopyright(“Copyright ©  2009”)]

[assembly: AssemblyTrademark(“”)]

[assembly: AssemblyCulture(“tr”)]

[assembly: AssemblyAlgorithmId(AssemblyHashAlgorithm.MD5)]

[assembly: AssemblyDefaultAlias(“DataLayer”)]

[assembly: ComVisible(false)]

[assembly: Guid(“41f2bb06-8f33-4321-8e41-76c503147f60”)]

[assembly: AssemblyVersion(“1.0.0.0”)]

[assembly: AssemblyFileVersion(“1.0.0.0”)]
[
assembly: AssemblyFlags(AssemblyNameFlags.EnableJITcompileOptimizer | AssemblyNameFlags.EnableJITcompileTracking)]

 

//Bu kod ile çalışan assembly içerisindeki custom attribute’lar listelenir.

Assembly asm = Assembly.GetExecutingAssembly();

object[] attrs = asm.GetCustomAttributes(false);

foreach (Attribute attr in attrs)

    Console.WriteLine(“Attribute:{0}”,attr.GetType());

 

Reflection Tipleri :

Bir nesnenin tipin 4 farklı şekilde alabiliriz. Bunlar ; Assembly sınıfı ile, Module sınıfı ile, bir nesnenin instance’ı ile veya typeof keywordu ile.

Type[] tt;

Assembly asm = Assembly.GetExecutingAssembly();

tt = asm.GetTypes();

 

Module[] mods = asm.GetModules();

Module m = mods[0];

tt = m.GetTypes();

 

object o = newobject();

Type t = o.GetType();

 

t = typeof(Int32);

 

Bu yöntemlerden biriyle tipi aldıktan sonra artık o tipin metodları,propertyleri, eventleri,interface’leri,kalıtım ağacı vs elimizin altında demektir.

 

Type t = typeof(String);

Console.WriteLine(” NameSpace : {0}”,t.Namespace);

Console.WriteLine(” FullName : {0}”, t.FullName);

Console.WriteLine(” IsValueType : {0}”, t.IsValueType);

Console.WriteLine(” IsSealed : {0}”, t.IsSealed);

Console.WriteLine(” IsAbstract : {0}”, t.IsAbstract);

Console.WriteLine(” IsPublic : {0}”, t.IsPublic);

Console.WriteLine(” IsClass : {0}”, t.IsClass);

 

//Bir sınıfın Property’lerini listelemek

Type t = typeof(System.Data.OleDb.OleDbCommand);

foreach (PropertyInfo item in t.GetProperties())

{

    Console.WriteLine(“{0} – {1}”,item.Name,item.MemberType);

}

//Bir sınıfın member’lerini listelemek

 Type t = typeof(System.Data.OleDb.OleDbCommand);

 //BindingFlagler ile filtre eklemek

BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

foreach (MemberInfo item in t.GetMembers(flags))

{

     if (item.MemberType == MemberTypes.Event) Console.WriteLine(“Bu bir Event”);

     elseif (item.MemberType == MemberTypes.Method) Console.WriteLine(“Bu bir Metod”);

      //…..

      Console.WriteLine(“{0} – {1}”, item.Name, item.MemberType);

}

 

Dinamik Kod Yazma : Buraya kadar mevcut olan dll’leri ve özelliklerini listelemeyi öğrendik artık referans olarak vermeden bir dll’i nasıl runtime’da çalıştırabiliriz ona bakacağız.

 

//Bu kod Hastable’ı referans göstermeden olusturup yeni bir hashtable yaratıyor.

Assembly asm = Assembly.LoadFile( @”C:WINDOWSMicrosoft.NETFrameworkv2.0.50727mscorlib.dll”);

Type hashType = asm.GetType(“System.Collection.Hashtable”);

//Constructoru parametre almayan

ConstructorInfo ctor = hashType.GetConstructor(Type.EmptyTypes);

object newHash = ctor.Invoke(newobject[] { });

 

MethodInfo meth = hashType.GetMethod(“Add”);

meth.Invoke(newHash, newobject[] { “Hi”, “Hello” });

//Yaratılan hastableın countu alınıyor.

PropertyInfo prop = hashType.GetProperty(“Count”);

int count = (int)prop.GetValue(newHash,null);

 

Örneğin bir sınıf içerisindeki statik metodları çağırmak istersek bu sefer sınıfın instance oluşturma işini atlayabiliriz.

 

Runtime’da Kod Oluşturma : Reflection sadece assembly ve tipleri hakkında bilgi alabilme ile sınırlı değildir. Reclection ile Runtime’da bir assembly oluşturabiliriz.

System.Reflection.Emit namespace’i altında bunu yapabilecek builder sınıfları mevcuttur. AssemblyBuilder bir assembly , MethodBuilder bir method , TypeBuilder bir tip oluşturmamıza imkan tanır.

İlk önce bir Assembly ve Module oluşturarak işlemlere başlayabiliriz.

 

//Runtime da Kod Oluşturma

AssemblyName asmName = newAssemblyName();

asmName.Name = “DinamikAssembly”;

AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName,

    AssemblyBuilderAccess.RunAndSave);

ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(“MainMod”, “DinamikAssembly.dll”);

//Yeni bir public sınıf oluşturuyoruz.

TypeBuilder typeBuilder = modBuilder.DefineType(“Sinif1”, TypeAttributes.Public | TypeAttributes.Class);

//Bir sınıf daha oluşturuldu.Base’i Hastable ve IDisposable ı implement edecek.

TypeBuilder typeBuilder2 = modBuilder.DefineType(“Sinif2”, TypeAttributes.Public | TypeAttributes.Class, typeof(Hashtable),newType[]{typeof(IDisposable)});

ConstructorBuilder ctorBuilder = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

ILGenerator codeGen = ctorBuilder.GetILGenerator();

codeGen.Emit(OpCodes.Ret);

//…………….

asmBuilder.Save(asmName+“.dll”);

 

Reflection ile ilgili anlatacaklarım bu kadar.Herkese iyi çalışmalar.

Reklamlar

Temmuz 14, 2010 - Posted by | C# | , , ,

1 Yorum »

  1. My brother recommended I would possibly like this web site.
    He was once entirely right. This put up truly made my day. You cann’t imagine simply how a lot time I had spent for this info! Thanks!

    Yorum tarafından diy cold sore treatment | Temmuz 18, 2013 | Cevapla


Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s