İlk olarak Extension Manegerden kastımızın extension metodlar olmadığını söylerek makalemize başlayalım. Peki nedir Extension Manager?Doğru bir isimlendirme mi bilemiyorum ama yaptığımız işi en iyi anlatan ifadenin bu olduğunu düşündüğüm için bu ismi verdim.Makalemizin başında Extension Metod olmadığını söylemiştik fakat bir bakıma benzer bir yapıdan bahsediyoruz.Şöyle ki; Extension Manager, kendi uygulamamız için kullanıcılara Extension Metod yazma özgürlüğü verme olarak nitelendirilebilir.Tam olarak extension metod değil tabi ama yakın bir mantık.Aslında EM’ye neden ihtiyacımız olacağını yazarsak sanırım konu daha iyi anlaşılacaktır.Şimdi şöyle bir senaryomuz olduğunu düşünelim, bir firmada çalışıyorsunuz ve sizden yazılım departmanı içinde web üzerinden kullanılacak basit bir mail projesi isteniyor yani masaüstü uygulaması değil Basitçe mail gönderecek-alacak ve listeleyecek bir proje diyelim.Projeyi hazırlıyorsunuz ilgili kullanıcılara dağıtıyorsunuz ve her biri kendine kurulumu yapıyor.Projeniz gayet güzel çalışıyor ama kullanıcılardan bazı istekler geliyor.Kimisi mail gönderilirken mail sonunda imza istiyor, kimisi tarih yazsın diyor, bazıları mail listelenirken mail başlığında mailin alma tarihi görünsün istiyor vs.Projeyi yazılım departmanı için yazdığınız için bu arkadaşların hepside kod yazmayı bilen insanlar.Bunuda göz önünde bulundurarak madem öyle, bu isteklere göre ben bir sistem yapayım herkes kendine göre istediği kısımları özelleştirsin diyorsunuz.Tabi bu özelleştirmeden kastımız bir panel yazmak değil.Yani bir panel yapalım mailin altında tarih görünsün seçeneği olsun onu seçince görünsün, tarihle ilgili bir madde olsun onu ayarlarsın vs. değil.Bizim bahsettiğimiz herkes kod bazında kendine göre özelleştirme yapabilsin.Peki bu özelleştirmeden kasıt tam olarak nedir? Buradan sonrasını beklediğiniz kısım olan kodlama üzerinde anlatırsak daha iyi olacaktır.Tabi burada oturup yukarıdaki mail projesini yazmayacağız, ekrana mesaj yazan basit bir web projesi yazacağız. İlk başta EM’siz halini yazacağız daha sonra düzenleyeceğiz. Karışıklık olmaması adına olabildiğince basit bir sistem olacak.Visual Studio’yu açalım, bir web projesi oluşturalım.Oluşturduğumuz web projesine bir class ekleyelim, ismi “Mail” olsun.İçeriğide şu şekilde olsun.using System;public class Mail{public string Mesaj { get; set; }}
Gördüğünüz gibi basit bir sistem sadece Mesaj isminde bir property var.Daha sonra Default.aspx dosyamızın kod kısmına geçerek Page_Load olayına aşağıdakileri yazalım.Mail p = new Mail();p.Mesaj = “Basit bir mesaj”;Response.Write(p.Mesaj);
Evet gayet basit bir sistem yaptık.Mail sınıfımız var ve bunu oluşturup içindeki Mesaj bilgisini ekrana yazıyoruz.Buraya kadar bir sorunumuz yok.Bu şekilde projemizi dağıttık ve daha sonra mesajın ekrana yazdırılmasıyla ilgili bazı ek özellikler istendi.Mesela birisi Mesaj’ın sonunda o anki tarih yazsın istiyor, diğeride tarihi istemiyor sadece kendi adı yazsın istiyor.Herkes farklı şeyler istiyor yani.Sizde projenin orjinali bozulmasın istiyorsunuz , diğer bir durum olarak ilgili kodlarınız dll içerisinde olabilir bu durumda basitçe mesaj yazdırma fonksiyonunu gidip düzenleyemezler.Öyleyse ne yapacağız? Bu yazılımcı arkadaşlar için mesaj ekrana yazdırılmadan önce kendi istedikleri işlemi yaptırabilmeleri için bir imkan sağlayacağız.Tabi bunu sağlarken orijinal kodlarımıza müdahale ettirmiyoruz.İlgili arkadaşımız kendi class’ının olduğu .cs dosyasını app_code klasörümüze koysun gerisine karışmasın.Tamam özelleştirelim hemen.Aşağıdaki gibi MesajDegis isminde bir class ekleyelim dosyamızın ismide MesajDegis.cs olsun ve app_code klasörümüze koyalım.MesajDegis.csusing System;public class MesajDegis{void MesajiDegistir(Mail m){m.Mesaj += “
Oğuzhan DEMİREL”;}}

Tamam mı ? Artık mesaj yazdırılırken ismimde sonuna eklenecek mi?Elbete ki hayır. Şu haliyle kendine gelen Mail sınıfındaki mesaj değerini değiştirebilen bir sınıf yazdık.Üstüne üstlük bu sınıfı kullananda yok.Öyle ya bu dosya sonradan eklendi kim bilecek içindeki MesajiDegistir metodunu? E peki ne yapacağız? Projemiz üzerinde bazı düzenlemeler yapıcağız ve yeni versiyon olarak piyasaya sunacağız.İhtiyacımız olan nedir? Mesaj ekrana yazdırılmadan önce kullanıcıların tanımladığı mesaj yazdırma ile ilgili olan metodlar varsa onları çalıştırmak ve sonra ekrana yazdırmak.Ama şöyle bir problemimiz var.Bu metodlar sonradan geliştiriciler tarafından ekleneceği için, ne isimlerini biliyoruz nede kaç tane olduklarını.O yüzden bu sorunu aşmak için EventHandler kullanıcaz.Yani mesaj yazdırılmasıyla ilgili bir eventimiz olacak geliştiriciler bu evente kendi metodlarını ekleyecekler.Biraz karışık oldu ama kodlaması kolay.Öncelikle daha sonradan karışıklık olmaması için MesajDegis.cs dosyamızı silelim daha sonra yenisini yazacağız.Şimdi basit olarak Mail sınıfımızı EventHandler destekli hale getirelim.using System;public class Mail{public string Mesaj { get; set; }//EventHandler kısmıpublic static event EventHandler Yazicam;public static void OnYazicam(Mail p, EventArgs e){if (Yazicam != null){Yazicam(p, e);}}}
Burada sadece “EventHandler kısmı” dediğimiz kodları ekledik.Basit olarak, static bir “Yazicam” isminde eventhandler ve bu eventi kullanan yine static “OnYazicam” metodunu ekledik.Mail sınıfımızda yapacağımız işlem bu kadar.Artık mesajımız ekrana yazdırılmadan önce çağırabileceğimiz bir eventimiz var.Geliştiriciler bu evente kendi metodlarını tanımlayabilecekler, bizim tek yapacağımız ise yazdırma işleminden önce bu eventi çalıştırdığımızdan emin olmak.Yani mesajı ekrana yazdırma sistemimiz şöyle olacak.Default.aspx dosyamızın kod tarafında şu düzenlemeyi yapıyoruz.Mail p = new Mail();p.Mesaj = “Basit bir mesajC”;//Geliştiricilerin metodlarını çalıştırMail.OnYazicam(p, new EventArgs());Response.Write(p.Mesaj);
Burda tek yaptığımız şey “Mail.OnYazicam(p, new EventArgs());” satırı ile Mail classımıza ait “OnYazicam” metodunu çağırmak oldu.Yani değişik bir durum yok.Ufak bir toparlama yapacak olursak, ilk yaptığımız basit projemize şu eklemeleri yaptık;1-Mail classımıza bir event sistemi ekledik2-Default.aspx dosyamızda da mesaj yazdırılmadan hemen önce bu event sistemini kullandıkBuraya kadar bir sorunumuz yok.Sistemimiz yaptık ve projemiz artık dağıtıma hazır.Artık mesajımız ekrana yazdırılmadan önce çalıştırdığımız bir event sistemimiz var, bu sayede isteyen geliştirici mesaj yazdırılmadan önce mesaj üzerinde istediği düzenlemeyi yapabilecek.Tamam yapalım öyleyse bu sisteme uygun bir harici kod dosyası.Yine ismi MesajDegis.cs olsun ve içeriği şu şekilde olsun;MesajDegis.csusing System;public class MesajDegis{public MesajDegis(){Mail.Yazicam += new EventHandler(Mail_Yazicam);}void Mail_Yazicam(object sender, EventArgs e){Mail m = sender as Mail;m.Mesaj += “
Oğuzhan DEMİREL”;}}

Şimdi yukarıda ne yaptık? Bir kurucu metodumuz var ve sınıfımız oluşturulduğunda bu kurucu metod ile projenin Mail sınıfındaki Eventine kendi metodumuzu ekliyoruz.Ama şöyle bir problemimiz var.Bu kurucu metodumuz hiçbir yerde çalıştırılmıyor.Öyle ya bu sonradan eklediğimiz bir dosya, her şeyden bağımsız yani.Peki bu durumda ne yapıcaz?Sonradan app_code klasörümüze eklenen bu classları bir şekilde kurmalıyız yani ufak derleyici mantığında bir sistem yapmalıyız.Bu sistem projemizin başlangıcında çalışmalı app_code içindeki BELİRLİ sınıfları oluşturmalı.Neden belirli sınıflar? Çünkü app_code içerisinde bizim yazdığımız birçok class olacak onların hepsini oluşturmasını istemeyiz.Peki bu belirleme işlemini neye göre yapacağız? Bildiğimiz gibi classlar, propertyler vs. ler için bir Attribute sistemimiz var.Bu sistem sayesinde derleyici ilgili elamanın nasıl davranacağını biliyor.Bizde kendi ufak derleyicimiz için aynı sistemi kullanacağız.Şöyle bir sistemimiz olacak,geliştiriciler harici olarak yazdıkları bu classları bizim belirleyeceğimiz bir attribute ile işaretleyecekler.Bu attribute’ye isim olarak Extension diyelim.Yani yukarıdaki MesajDegis.cs dosyamızda classımızın Extension olduğunu belirtmeliyiz ki yazacağımız derleyici ona göre bu classı kursun.Önce Attributemizi oluşturalım.Yeni bir class ekleyelim ismi ExtensionManager.cs olsun.Kendi Attributemizi tanımlarken Attribute sınıfından kalıtım almalıyız ve classımızın isminin sonu Attribute olmalı.using System;public class ExtensionAttribute : Attribute{}
Artık derleyicimiz için gerekli Extension özelliğimizide tanımladık.Şimdi en basit haliyle derleyici metodumuzu yazalım.Bu metodu uygun olan istediğiniz bir yerde yazabilirsiniz, önemli olan başlangıçta çalıştırmaktır.Ben bir bütünlük olması açısından Attribute miz içerisinde kullanıcam.Attributemizin son hali aşağıdaki gibi olacaktır.using System;using System.Reflection;public class ExtensionAttribute : Attribute{public static void Derle(){// App_Code içerisindeki classlarımıza ait dll dosyamızı asm değişkenimize yüklüyoruz.Assembly asm = Assembly.Load(“__code”);// asm değişkenimiz içerisindeki class vs. leri alıyoruz.Type[] types = asm.GetTypes();foreach (Type type in types){// İlgili nesneye ait Attribute özelliklerinin tümünü attributes değişkenine alıyoruzobject[] attributes = type.GetCustomAttributes(typeof(ExtensionAttribute), false);foreach (object attribute in attributes){// Eğer ilgili nesne [Extension] ile işaretlenmişse// asm.CreateInstance(type.FullName) ile ilgili classı kurucu metodu ile oluşturuyoruz.// Böylece eventimize gerekli ekleme yapılmış oluyor.if (attribute.GetType().Name == “ExtensionAttribute”) asm.CreateInstance(type.FullName);}}}}
Kodların üzerine gerekli açıklamaları yaptığım için ek bir açıklama yapmıyorum.Artık yapmamız gereken tek bir şey kaldı.Bu Derle metodumuzu projemizin başlangıcına eklemek.Bunun için en uygun yer “Global.asax” dosyamızın “Application_Start” metodudur.Eğer “Global.asax” dosyanız yoksa, projenize sağ tıklayıp “Globol Application Class” dosyası ekleyebilirsiniz. “Application_Start” metodunun içinede kodumuzu ekliyoruz.void Application_Start(object sender, EventArgs e){ExtensionAttribute.Derle();}
Artık Extension Metod destekli bir sisteminiz var.Bundan sonrası hayal gücünüze kalmış.En basit haliyle sistem bu şekilde olacaktır.Dediğim gibi en basit hali bu.Ek olarak neler yapabilirsiniz?-Extension metodlara bir öncelik sırası ekleyebilirsiniz.Yani mesaj yazdırılmadan önce çalıştırılan 5 farklı metod olabilir hangisinin önce çalıştırılacağına karar verebilirsiniz.-Şu haliyle sadece app_code içerisindeki kodlar dikkate alınıyor, kendi code klasörlerinizi yapabilirsiniz ve ordakilerinde derlenmesini sağlayabilirsiniz.-Code dosyasına ek olarak dll dosyalarınıda derleyicinizde kullanabilirsiniz.-Extension attributenizi geliştirebilirsiniz.Geliştiricinin adı, metodun adı, açıklama, oluşturma tarihi, version gibi özelliklerde ekleyebilirsiniz.Aklıma gelenler bunlar.Kodlamadan daha çok mantığın anlaşılması için uğraştım.Böylece kendinize göre istediğiniz düzenlemeyi yapabilirsiniz.Bu makalemin devamı olarak bir sonraki makalede biraz daha kod ağırlıklı olarak metodlara öncelik vermeyi anlatacağım.