C# Castle Windsor ve IoC Container Kullanımı

By Burak TUNGUT - 13.6.2013 - Kategori C#

Herkese Merhabalar,

2. sınıfa veda ettik, güzel bir yaza girişte yaptık derken farkettim ki uzun süredir makaleleri aksattımsmiley Daha fazla arayı soğutmadan hemen bir makaleye giriş yapalım.
Bir önceki makalemde C# ile Dependency Injection ve Loosely Coupling konusuna değinmiştik.Inversion of Control Container Aslında makalenin sonunda bu konuya daha farklı bir bakış açısı ile devam edeceğimizden bahsetmiştim.

Öyle sanıyorum bir önceki makalemde verdiğim örnekten dolayı artık sıkı bağlı tiplerden ve bu formu sağlayacak kodlamalardan uzaklaşacağız. Zaten makalede verdiğimiz örneği, Dependency Injection'ın hakkını vererek tekrar revize etmiş idik.

IoC Container

Bu makale de ise olayı bir kademe daha ileriye taşıyacağız. Bir önceki makale de işi yürütecek ve bundan önce instance alma işlemini yapacak kısmı bir metotda yapıyorduk. Böyle bir yapıda ise, söz konusu tipe işimiz her düştüğünde bir instance daha alınacak ve aynı işlemler tekrarlanacak.
Oysaki IoC Container'lar sayesinde, instance işlemini bir kereliğe mahsus yaptırabilir ve tipi kullanacağımız her bir işlemde ise bir önceki instancenin kullanılmasını sağlayabiliriz.

Envarterlerin İndirilmesi

Şu anda yapacağımız işlemlere karar verdik. Sıra sorunumuzu çözecek babayiğit bir IoC kütüphanesi bulmakta. Aklıma ilk gelen Microsoft ürünü olan, Ninject ve Castle Projects adı altında geliştirilen Windsor kütüphanesi.

Bu makalemde Windsor kütüphanesini kullanıyor olacağız. Tabi ki kodlama kısmına geçmeden önce kütüphanemizin en son sürümünü buradan indirelim.
İndirdiğimiz dosya içerisinden Castle.Core ve Castle.Windsor kütüphanelerini projemize ekleyelim.

Mouse ve Base Tiplerimiz

Hatırlarsanız bir önceki makalede son olarak bir adet IMouse adında bir interfaceimiz ve bu interfaceyi implemente eden iki farklı mouse tipimiz mevcuttu. Toplam da bu 3 tipi yeni projemiz de yine kullanıyor olacağız. Bu nedenle aşağıdaki tipleri projemize dahil edelim.

interface IMouse
    {
        void Write();
    }

 

class LogitechMouse : IMouse
    {
        public void Write()
        {
            Console.WriteLine("Logitech Mouse Kullanıldı");
        }
    }

    class A4TechMouse : IMouse
    {
        public void Write()
        {
            Console.WriteLine("A4Tech Mouse Kullanıldı");
        }
    }

Windsor Container ve Util Sınıfımız

Yukarıda kullanılacak tüm tiplerimizin, bir container içerisinde bekletileceğinden bahsetmiştik. Böylece tip ile ilgili bir işlem yapacağımızda ne bir daha instance almak için uğraşağıcaz. Ne de hangi tipin kullanılacağına karar vermek için uğraşacağız. Bu sayede uygulama akışının, runtime anında değiştirilmesini sağlamış olacağız.

Bunun için IoC adında bir adet static sınıf yazalım. Sınıfımızın kodları aşağıdaki gibi olacaktır;

public static class IoC
    {
        private static readonly IWindsorContainer container = new WindsorContainer();

        public static void A4TechFactory()
        {
            container.Register(
                Component.For<IMouse>().ImplementedBy<A4TechMouse>()
                );
        }

        public static void LogitechFactory()
        {
            container.Register(
                Component.For<IMouse>().ImplementedBy<LogitechMouse>()
                );
        }

        public static T ResolveMouse<T>()
        {
            return container.Resolve<T>();
        }
    }

Yukarıdaki kodda değinmek istediğim ilk kısım container adlı değişkenimiz. İşte tüm instanceleri içerisinde tutacak ve gerektiğinde doğru tipi bize ulaştıracak nesne tam olarak burada. IWindsorContainer interfaceini implemente eden WindsorContainer adlı sınıftan bir adet instance alıyoruz. Static sınıf içerisinde çalışmamızı sürdürdüğümüz içinde nesnemiz singleton yapıda olacaktır.

Tabi ki bir üst katmanda yani IoC sınıfını kullanarak mouse tiplerinden birini elde etmek isteyen kısıma doğru tipi verebilmek için öncelikle container içerisinde bu tiplerin kaydedilmesi gerekmektedir. Bunun için iki farklı mouse tipinide kayıt edecek iki farklı metot yazıyoruz.

LogitechFactory adlı metot IMouse interfaceini implemente eden LogitechMouse adlı sınıftan bir adet instance alınmasını ve container içerisine eklenmesini sağlarken, A4TechFactory de aynı işlemi A4TechMouse tipi için yapmaktadır.

Bunu sözlü olarakta ifade etmemiz mümkün. Yani LogitechFactory metodu tetiklendiğinde container şunu düşünmekte ; "Benden IMouse tipi için bir istek gelirse, LogitechMouse tipini geri göndereceğim"

Şu anda tiplerimizin kaydedilmesini sağladık. Bir de kaydedilen tipe ulaşılmasını sağlayacak bir metot yazmalıyız. Aslında IWindsorContainer interfacesi Resolve adlı bir metot içermektedir. Bu metoda gönderilecek bir generic tip, container içerisinden seçilip geri gönderilir. Fakat container nesnesini private olarak tanımladığımız için bu metoduda çağıracak başka bir metod yazmalıyız. Bunun içinde ResolveMouse adlı metodu kullanacağız.

Tiplerin Kaydedilmesi ve Kullanılması

Şu anda tiplerin kaydedilmesini ve kaydedilen tipin seçilip, geri getirilmesini sağlayacak tüm metotları yazdık. Şimdi ise projeyi deneyeceğimiz console applicationın main metodunu tasarlayalım. Aslında bakacak olursak çokta fazla bir kod yazmayacağız. Çünkü az önce yazdığımız IoC sınıfı tüm işlemlerimizi harika bir şekilde gerçekleştirecektir.

Tek yapmamız gereken hangi mouse tipini kullanacaksak, o tip için yazdığımız factory metodunu tetiklemek ve program akışta iken tipi Resolve ederek içerisindeki Write metodunu tetiklemek olacaktır.
LogitechMouse tipi için aşağıdaki kodu deneyebilirsiniz;

class Program
    {
        static void Main(string[] args)
        {
            IoC.LogitechFactory();

            IoC.ResolveMouse<IMouse>().Write();
        }
    }

Yukarıdaki kod ile öncelikle IMouse tipini baz alarak LogitechMouse tipinde bir adet instance alınacak ve alınan instance container'a eklenecektir.
Ardından gelen Resolve metodu ile container içerisinde IMouse tipi için kaydedilmiş instance alınacak ve içerisindeki Write metodu tetiklenecektir.

Bir sonraki makalemde görüşmek üzere, herkese esenlikler dilerim :)
H.Burak TUNGUT

Yorum Bırak

Facebook
Son Yorumlar