C# Event Kullanımı Örneği

Bu makalemde C# Event Kullanımı hakkında bir örnek yaparak çokça zorlanılan Event konusunu güncel ve kullanılabilir bir örnek üzerinden anlatmaya çalışacağım. Ayrıca event konusunda detaylı bilgi almak isteyenler aşağıda ki makalemde faydalanabilirler.

C# Event Nedir? Nasıl Kullanılır?

https://alkanfatih.com/c-event-olay-nedir-nasil-kullanilir/

Event Nedir?

Kısaca anlatmak gerekirse Event, bir programda meydana gelen eylemlerdir. Eventler, bir sınıf veya nesnenin, bir eylem olduğunda diğer sınıfları veya nesneleri bilgilendirmesine izin verir. Event oluşturmada iki önemli yapı vardır.

  • Publisher: Eylemi başlatan (veya gönderen) sınıfa denir.
  • Subscriber: Eyleme alan (veya işleyen (handle)) sınıflara denir.

Şimdi şöyle bir senaryomuz olduğunu düşünelim. Bir sipariş otomasyonunda sipariş geldiği anda sistem çalışanlarına mail ve sms ile bilgilendirilme yapacağız. Böyle bir modülü event kullanımını bilmediğimiz varsayarsak şu şekilde gerçekleştirebiliriz.

public class Order
{
    public void Create()
    {
        Console.WriteLine("Order created");
        Email.Send();
        SMS.Send();
    }
}
public class Email
{
    public static void Send()
    {
        Console.WriteLine("Send an email");
    }
}
public class SMS
{
    public static void Send()
    {
        Console.WriteLine("Send an SMS");
    }
}

Order sınıfının Create adlı metodunu her çağırdığımızda metot içerisinde Email ve SMS sınıflarının Send metotlarını da çağırdığımızdan dolayı işverene bilgilendirme maili ve sms’i gidecektir. Ama bu iyi bir dizayn değildir.

Böyle bir yapıyı en iyi şekilde tasarlayabilmek için publisher/subscriber pattern kullanmamız daha doğrudur. Burada:

  • Order sınıfı publisher (yayıncıdır).
  • E-posta ve SMS sınıfları subscribers (abonelerdir).

Eğer event kullanırsak bir sipariş oluşturulduğunda, Order nesnesi, Email ve SMS sınıflarını e-posta ve SMS göndermeleri için bilgilendirir.

Event Deklare Etmek

public delegate void OrderEventHandler();

public class Order
{
    public event OrderEventHandler OnCreated;
    public void Create()
    {
        Console.WriteLine("Order created");
    }
}

Nasıl çalışır?

  • İlk olarak, event için bir delegate türü tanımlayın.
delegate void OrderEventHandler();
  • İkinci olarak, delegate türüyle ilişkili bir event bildirin:
public event OrderEventHandler OnCreated;

Event Çağırma

Herhangi bir event handler olmayan bir event boştur (null). Bu nedenle, bir event’i çağırmadan önce onun null olup olmadığını kontrol etmeniz gerekir.

public delegate void OrderEventHandler();
public class Order
{
    public event OrderEventHandler OnCreated;
    public void Create()
    {
        Console.WriteLine("Order created");
        if (OnCreated != null)
        {
            OnCreated.Invoke();
        }
    }
}

Event Katılma (Subscribing)

Event subscribing, bir event’e event handler’ları eklemek anlamına gelir. Olay işleyicileri, olayın temsilcisi ile aynı dönüş türüne ve imzaya sahip olmalıdır. Bir event’e event handler eklemek için += operatörünü kullanırsınız. Bir event handler bir instance metot, statik metot, anonim metot veya bir lambda ifadesi olabilir.

Aşağıda, OnCreated olayına nasıl Subscribing olucağı gösterilmektedir:

internal class Program
{
    private static void Main(string[] args)
    {
        var order = new Order();
        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}

Sonuç:

Order created
Send an email
Send an SMS

Nasıl Çalışır?

İlk olarak, yeni bir Order nesnesi oluşturun:

var order = new Order();

İkinci olarak, OnCreated event’ine event handler’lar ekleyin:

order.OnCreated += Email.Send;
order.OnCreated += SMS.Send;

Üçüncü olarak, Order nesnesinin Create() metodunu çağırın:

order.Create();

Create() metodu, OnCreated event’ini başlatır. E-mail ve SMS sınıfları, OnCreated olayına abone olduklarından, bu sınıfların Send() metotları otomatik olarak çağrılır.

Kodun Bütünü:

internal class Program
{
    private static void Main(string[] args)
    {
        var order = new Order();
        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}
public delegate void OrderEventHandler();
public class Order
{
    public event OrderEventHandler OnCreated;
    public void Create()
    {
        Console.WriteLine("Order created");
        if (OnCreated != null)
        {
            OnCreated.Invoke();
        }
    }
}
public class Email
{
    public static void Send()
    {
        Console.WriteLine("Send an email");
    }
}
public class SMS
{
    public static void Send()
    {
        Console.WriteLine("Send an SMS");
    }
}

EventHandler

C#, event kullandığınızda yeni bir delegete türü tanımlamanıza gerek kalmaması için size standart EventHandler delegate türü sağlar.

Aşağıda, EventHandler delegate türünün bildirimi gösterilmektedir:

public delegate void EventHandler(object sender, EventArgs e);

Bu delegate türünde:

  • sender, eventi başlatan nesneye bir referans tutar.
  • EventArgs nesnesi, uygulama için geçerli olan durum bilgisini tutar.

EventArgs’ın, publisher’den (yayıncıdan) subscribers (abonelere) veri iletmesi gerekmeyen event handlers (olay işleyicileri) için tasarlandığını anlamak önemlidir. Dataları iletmek istiyorsanız, EventArgs sınıfından türetilmiş bir sınıf tanımlamanız gerekir.

Aşağıdaki program, oluşturulan order event için EventHandler’ın nasıl kullanılacağını gösterir:

internal class Program
{
    private static void Main(string[] args)
    {
        var order = new Order();
        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create();
    }
}
public delegate void EventHandler(object sender, EventArgs e);
public class Order
{
    public event EventHandler OnCreated;
    public void Create()
    {
        Console.WriteLine("Order created");
        if (OnCreated != null)
        {
            OnCreated(this, EventArgs.Empty);
        }
    }
}
public class Email
{
    public static void Send(object sender, EventArgs e)
    {
        Console.WriteLine("Send an email");
    }
}
public class SMS
{
    public static void Send(object sender, EventArgs e)
    {
        Console.WriteLine("Send an SMS");
    }
}

Nasıl Çalışır?

İlk olarak, OrderEventHandler delegate türü yerine EventHandler’ı kullanın:

public event EventHandler OnCreated;

İkinci olarak, Order nesnesini (this) ve EventArgs.Empty’yi ileterek OnCreated event’ine entegre edin.

OnCreated(this, EventArgs.Empty);

EventArgs.Empty öğesinin, event datası olmayan bir event kullanılacak bir değer sağladığını unutmayın.

Üçüncü olarak, Email ve SMS sınıflarının Send() metodunun imzasını EventHandler delegate türüyle eşleşecek şekilde değiştirin:

public static void Send(object sender, EventArgs e)

EventArgs ile Data Gönderme

Publisher’den (Yayıncıdan) subscriber’lara (abonelere) event handler’ın ikinci parametresindeki verileri iletmek için, EventArgs sınıfından miras alan bir sınıf tanımlamanız ve iletmek istediğiniz verileri sınıfta depolamanız gerekir.

Aşağıdaki program, Publisher’den (Order sınıfı) verilerin (E-mail ve Telefon parametrelerinin) subscriber’lara (E-mail ve SMS sınıfları) nasıl iletileceğini göstermektedir.

internal class Program
{
    private static void Main(string[] args)
    {
        var order = new Order();
        order.OnCreated += Email.Send;
        order.OnCreated += SMS.Send;

        order.Create("alkanfatih@hotmail.com.tr", "554-554-54-54");
    }
}
public class OrderEventArgs : EventArgs 
{
    public string Email { get; set; }
    public string Phone { get; set; }
}
public class Order
{
    public event EventHandler<OrderEventArgs> OnCreated;
    public void Create(string email, string phone)
    {
        Console.WriteLine("Order created");
        if (OnCreated != null)
        {
            OnCreated(this, new OrderEventArgs { Email = email, Phone=phone });
        }
    }
}
public class Email
{
    public static void Send(object sender, OrderEventArgs e)
    {
        Console.WriteLine($"Send an email to {e.Email}");
    }
}
public class SMS
{
    public static void Send(object sender, OrderEventArgs e)
    {
        Console.WriteLine($"Send an SMS to {e.Phone}");
    }
}

Sonuç:

Order created
Send an email to alkanfatih@hotmail.com.tr
Send an SMS to 554-554-54-54

Nasıl Çalışır?

İlk olarak, EventArgs sınıfından miras alan OrderEventArgs sınıfını tanımlayın:

public class OrderEventArgs : EventArgs 
{
    public string Email { get; set; }
    public string Phone { get; set; }
}

İkinci olarak, OrderEventArgs türüyle EventHanlder’ı kullanarak event tanımlayın:

public event EventHandler<OrderEventArgs> OnCreated;

Üçüncüsü, OrderEventArgs sınıfının bir eventini ve yeni bir örneğini oluşturun:

OnCreated(this, new OrderEventArgs { Email = email, Phone=phone });

Bu ifadede, OrderEventArgs nesnesi, e-mail ve phone verilerini içerir.


Özet

  • Event’ler, bir sınıf veya nesnenin, bir olay olduğunda diğer sınıfları veya nesneleri bilgilendirmesine izin verir.
  • Event’ler, publisher’ın (yayıncının) bir olay oluşturduğu ve subscribers’ın (abonelerin) even’e yanıt verdiği bir publisher/subscriber (yayıncı/abone) modelinde kullanılır.
  • Bir event’i bildirmek için delegate türü olarak EventHandler’ı kullanın.
  • Publisher’den (Yayıncıdan) subscribers’lara (abonelere) veri iletmek için EventArgs sınıfını genişletin.