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.

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

1 Comment »

  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!

    Comment by diy cold sore treatment | July 18, 2013 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s