Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C#’ta Öznitelik(Attribute) Oluşturma

Merhaba,

Teee ne zamanlar MVC Attribute Oluşturma başlıklı yazımda Asp.NET MVC mimarisine özel Attribute oluşturma konusunu ele almıştım. Şimdi ise C# ile özel öznitelik(Attribute) oluşturmayı inceleyeceğiz.

Attribute yapıları aslında arka planda bir class tanımlamalarıdır. C#’ta bir Attribute tanımlarken ilgili class’a Attribute olduğunu bildirmek için “Attribute” sınıfından türetmemiz ve ardından “AttributeUsage” Attribute’u ile hangi elemanlar üzerinde çalıştırılabileceğini belirtmemiz yeterlidir.

    [System.AttributeUsage(AttributeTargets.Method)]
    class KontrolAttribute : Attribute
    {
        public KontrolAttribute()
        {
            Console.WriteLine("Kontrol Attribute tetiklenmiştir." );
        }
    }

Yukarıdaki kod bloğunu incelersek eğer bir önceki paragrafta bahsettiğimiz gibi “KontrolAttribute” sınıfını öznitelik olarak kullanabilmek için “Attribute” sınıfından türettik ve “AttributeUsage” özniteliği sayesinde bu özniteliğin sadece metodlarda çalışacağını belirttik.

C#'ta Öznitelik(Attribute) Oluşturma

Yukarıdaki görüntülere bakarsanız eğer AttributeTargets Enumaration’ının hangi değerleri alabildiğini görebilirsiniz. Anlayacağınız field’dan tutun deletate’lere kadar tüm yapılara özel öznitelik tanımlayabilmekteyiz.

    class OrnekClass
    {
        [Kontrol()]
        public void OrnekMetod()
        {

        }
    }

Bildiğiniz gibi oluşturduğumuz özniteliği yukarıdaki gibi kullanabilmekteyiz. Tabi öznitelik sınıfımız Attribute sınıfından türetildiği için “classname[Attribute]” şeklinde tanımlansada bir öznitelik olduğu için çağrıldığı yerde classname’i yazmamız yeterlidir.

Şimdi property ve metodlara özel iki çalışma göstereceğim. Siz değerli okuyucularım, yaptığım bu çalışmaları diğer elemanlara genelleyebilirsiniz.

Property’e Özel Attribute

    [AttributeUsage(AttributeTargets.Property)]
    class KontrolAttribute : Attribute
    {
        public int Para { get; set; }
    }

Özniteliği kullanacağımız propertynin bulunduğu sınıfı inşa edelim.

    class AlisVeris
    {
        public AlisVeris(int Fiyat)
        {
            this.Fiyat = Fiyat;
            foreach (var property in typeof(AlisVeris).GetProperties())
            {
                foreach (var attr in property.GetCustomAttributes(false))
                {
                    if (property.Name == "Fiyat")
                    {
                        KontrolAttribute kontrolAttribute = (KontrolAttribute)attr;
                        if ((int)property.GetValue(this) > kontrolAttribute.Para)
                            Console.WriteLine("Alışveriş yapıldı.");
                        else
                            Console.WriteLine("Para eksik");
                    }
                }
            }
        }


        [Kontrol(Para = 100)]
        public int Fiyat { get; set; }
    }

Yukarıdaki kod bloğunu incelerseniz eğer, propertyi kullanacağımız sınıfın constructerında bu sınıfa bağlı propertylere tanımlanmış tüm attributeları tetiklemekteyiz. Örnekte yaptığımız algoritmada Fiyat propertysinin Kontrol Attribute’una verilen değer ile kıyaslaması yapılmaktadır.

AlisVeris sınıfı aşağıdaki şekilde örneklendirildiğinde ise,

    class Program
    {
        static void Main(string[] args)
        {
            AlisVeris alisVeris = new AlisVeris(150);
            AlisVeris alisVeris2 = new AlisVeris(10);
            Console.Read();
        }
    }

C#'ta Öznitelik(Attribute) Oluşturma
sonucunu vermektedir.

Şimdi benzer bir mantıkla metodlara özel Attributeları inceleyelim.

Metoda Özel Attribute

    [AttributeUsage(AttributeTargets.Method)]
    class KontrolAttribute : Attribute
    {
        public void Durum(bool Durum)
        {
            if (Durum)
                Console.WriteLine("Kontrol tamamlandı...");
            else
                Console.WriteLine("Kontrol ediliyor...");
        }
    }

İlgili özniteliği kullanacak metodu barındıran sınıfımızı inşa edelim.

    class AlisVeris
    {
        public AlisVeris(bool Durum)
        {
            foreach (var method in typeof(AlisVeris).GetMethods())
            {
                foreach (var attr in method.GetCustomAttributes(false))
                {
                    if (method.Name == "AlisVerisYap")
                    {
                        KontrolAttribute kontrolAttribute = (KontrolAttribute)attr;
                        kontrolAttribute.Durum(Durum);
                        AlisVerisYap(Durum);
                    }
                }
            }
        }

        [Kontrol]
        public void AlisVerisYap(bool Durum)
        {
            if (Durum)
                Console.WriteLine("Alış veriş yapıldı.");
            else
                Console.WriteLine("Alış veriş yapılamadı");
        }
    }

Yukarıdaki kod bloğunu incelersek eğer ilgili sınıfın tipinde bulunan metodlara bağlı attributelar tetiklenmekte ve basit bir algoritmik işlem gerçekleştirilmektedir.

Bu şekilde AlisVeris sınıfından aşağıdaki gibi nesne ürettiğimizde ise,

    class Program
    {
        static void Main(string[] args)
        {
            AlisVeris alisVeris = new AlisVeris(true);
            AlisVeris alisVeris2 = new AlisVeris(false);
            Console.Read();
        }
    }

C#'ta Öznitelik(Attribute) Oluşturma
sonucunu elde etmekteyiz.

AllowMultiple Özelliği

AllowMultiple özelliği ile oluşturulacak Attribute’un çoklu kullanım iznini ayarlayabilmekteyiz.
C#'ta Öznitelik(Attribute) Oluşturma
Gördüğünüz gibi AllowMultiple özelliği varsayılan olarak false değerine sahiptir.
C#'ta Öznitelik(Attribute) Oluşturma
true değerini verdiğimizde aynı yapı üzerinde birden fazla kullanım sağlayabilmekteyiz.

Inherited Özelliği

Bu özellik sayesinde oluşturduğumuz Attribute ile işaretlenen sınıflardan kalıtım alan başka sınıfların örneklendirmesinde Attribute’un işlevselliğini ayarlamaktayız. Varsayılan olarak true değerine sahiptir.

    [AttributeUsage(AttributeTargets.All, Inherited = false)]
    class KontrolAttribute : Attribute
    {
        public void Metod()
        {
            Console.WriteLine("Attribute tetiklendi.");
        }
    }

Eğer ki, Inherited özelliğine yukarıdaki gibi false değerini verip aşağıdaki gibi Kontrol özniteliğiyle işaretlenmiş sınıftan kalıtım alan sınıfın nesnesini alırsak artık bu öznitelik Derived Class’ta gerçeli olmayacaktır.

    class OrnekClass2 : OrnekClass
    {

    }

    [Kontrol]
    class OrnekClass
    {

    }

Evet, şimdi OrnekClass2 nesnesi yaratır ve ilgili tipe bağlı attribute var mı? yok mu? kontrol edersek eğer,
C#'ta Öznitelik(Attribute) Oluşturma
aşağıdaki hatayı alacağız.

Eee buda gayet doğal. Nihayetinde Inherited özelliğine false değer vererek kalıtsal durumlarda özniteliklerin işlevselliğini pasifize etmiş olduk.

Bir yazımızın daha sonuna gelmiş bulunmaktayız.

Sonraki yazılarımda görüşmek üzere…

İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

6 Cevaplar

  1. Melih dedi ki:

    Adamsın

  2. Bülent dedi ki:

    hocam emeğinize sağlık bende bikaç gündür bu custom attribute konusuna kafa yoruyorum eğer vakit bulupta cevaplarsanız size kafama takılan bir soru yöneltmek istiyorum
    bu attribute ları tanımladıktan sonra reflection ile kodları uygulayacağımız class içine yazıyoruz ama bu şekilde genel bir attribute yazamıyoruz yani bir attribute oluşturmuşsak bunun reflection kodlarını uygulayacağımız her sınıf için ayrı ayrı yazmamız gerekiyor ama mesela atıyorum hocam framework un kendi içinde olan Required atrribute sadece property ye uyguluyoruz gidipte bunun reflection kodlarını ayrıca kendi classlarımızda ayrı ayrı yazmıyoruz yani bu kendi yazdığımız attribute ları generic yapabilirmiyiz yani kodları etki ettirileceği class içine değilde mesela attribute içerisine mümkün değilse class yada property parametresi alarak bu şekilde sadece bir defa yazıp bir daha tekrardan kurtulma imkanımız olurmu

  3. Kamil Yasin Ablay dedi ki:

    Teşekkürler

  4. samet yorgun dedi ki:

    hocam elinize sağlık .login işlemi için bir attiribute yazdım rol kontrolü için
    biraz yeniyimde bir sorum olacaktı attiribute i yazıp IActionResult ımda belirttikten sonra durmadan döngüye giriyor . Bunun nedeni nedir

    • samet yorgun dedi ki:
              public override void OnActionExecuting(ActionExecutingContext filterContext)
              {
                  var rolid = filterContext.HttpContext.Session.GetString("rolid");
                  if (rolid=="1")
                  {
      
                      var controller = (HomeController)filterContext.Controller;
                      filterContext.Result = controller.RedirectToAction("Admin", "Home");
                      //filterContext.HttpContext.Response.Redirect("/Home/Admin");
      
                  }
                  else
                  {
                      filterContext.HttpContext.Response.Redirect("/Home/index");
                  }
                  base.OnActionExecuting(filterContext);
              }
      

Melih için bir yanıt yazın Yanıtı iptal et

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir