30 Ekim 2013 Çarşamba

Farkli Bir Assembly'deki Internal Metodu Reflection Ile Cagirma


Merhaba Arkadaşlar,

Bildiğiniz üzere nesne yönelimli programlamada, bir sınıfın private erişim belirleyecisi(access modifiers) ile tanımlanmış öğelerine(class, struct, method, property, field) kapsülleme mantığı gereği o sınıf dışında ulaşamıyoruz. Yine hatırlarsanız internal erişim belirleyicisi ile tanımlanmış öğeler ise bulunduğu assembly’nin dışında erişime kapalıdır. Fakat gün geldi erişime kapalı bir öğeyi kullanmaya ihtiyacınız oldu ya da sırf gıcıklığına buna yeltendiniz; o zaman okumaya devam edin :]

Derleme zamanında farklı assembly'deki internal öğelere erişme şansımız yok ama reflection'ı kullanarak yürütme zamanında bu öğelere ulaşabiliriz. Örnek üzerinden ilerleyelim;

Visual Studio ile "MathProject" adlı bir Blank Solution oluşturup içerisine "MathLib" adıyla bir Class Library projesi ekleyelim. MathLib projesi şu sınıfı içeriyor olsun;
namespace MathLib {
    internal class MathHelper {
        internal int Add(int number1, int number2) {
            return number1 + number2;
        }
    }
}
Senaryo gereği Math helper sınıfı ve Add metodu internal olarak tanımlı. MathLib projesini build edip dll çıktısının oluşmasını sağladıktan sonra MathProject solution'ına "MathConsoleApp" adıyla bir Console Application ekleyelim. Program.cs dosyasını aşağıdaki gibi düzenleyelim;
using System;
using System.Reflection;

namespace MathConsoleApp {
    class Program {
        static void Main(string[] args) {
            // assembly'nin bulunduğu yol alınır
            string projectPath = System.IO.Path.Combine(Environment.CurrentDirectory, @"..\..\..");
            string assemblyPath = System.IO.Path.Combine(projectPath, @"MathLib\bin\Debug\MathLib.dll");

            // assembly oluşturulur
            Assembly assembly = Assembly.LoadFile(assemblyPath);
            // istenen tip  bilgisiyle oluşturulan assembly üzerinen oluşturulur
            Type type = assembly.GetType("MathLib.MathHelper");
            // istenen tip'in nesne örneği alınır
            object instance = assembly.CreateInstance("MathLib.MathHelper");
            // reflection ile imzası bilinen metod tanımı oluşturulur
            MethodInfo addMethod = type.GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance);
            // reflection ile metod çağrılır
            object result = addMethod.Invoke(instance, new object[] { 2, 3 });

            Console.WriteLine("2 + 3 = " + result);
        }
    }
}
MathConsoleApp uygulamasını çalıştırdığınızda "2 + 3 = 5"  çıktısını verdiğini göreceksiniz. Bu blog girdisi ile dikkat çekmek istediğim bir konu "eklenti (plug-in) tabanlı" yazılım geliştirmedir, araştırmanızı tavsiye ederim.

Reflection'da dibine vurmanız ve kendinize iyi bakmanız dileklerimle :]

2 yorum: