Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

Reflection Kullanarak Generic Singleton Tasarım Deseni

Singleton pattern’i bildiğiniz gibi bir sınıfın sadece tek bir nesnesini oluşturmak için kullanıyordurk . Peki bir sınıfın neden sadece tek bir nesnesini oluşturma ihtiyacımız olabilir örneğin DataAccessLayer ınızda connection oluşturacaksınız. Bunun için bu pattern oldukça kullanışlı olabilir çünkü connection nesnenizde size sadece 1 tanesi yeterli. Siz new ile yeni bir nesnesini oluşturmak yerine mevcut connectionı kullanmanız daha mantıklı ve performanslı olacaktır.

Peki generic singleton patterni neden kullanıyoruz adından da anlaşılacağı gibi yapılan pattern’i bütün sınıflar için kullanabilelim. Şu andan itibaren bütün konsantrasyonumuzu bu yöne verelim.

Sınıfın instance’ını  Singleton<T>.Instance şeklinde kullanmayı hedefleyeceğiz.Singleton’unun temel prensibi sınıfın constructor’unun public olmaması, bu ne demek? new() keyword’u ile sınıfın nesnesini oluşturamıyoruz demek.

</pre>
<code> </code>
<pre id="pre0">public static class Singleton<T>
       where T : class
{
  static volatile T _instance;
  static object _lock = new object();

  static Singleton()
  {
  }

  public static T Instance
  {
    get
    {
      if (_instance == null)
        lock (_lock)
        {
          if (_instance == null)
          {
            ConstructorInfo constructor = null;

            try
            {
              // Binding flags exclude public constructors.
              constructor = typeof(T).GetConstructor(BindingFlags.Instance |
                            BindingFlags.NonPublic, null, new Type[0], null);
            }
            catch (Exception exception)
            {
              throw new SingletonException(exception);
            }

            if (constructor == null || constructor.IsAssembly)
            // Also exclude internal constructors.
              throw new SingletonException(string.Format("A private or " +
                    "protected constructor is missing for '{0}'.", typeof(T).Name));

            _instance = (T)constructor.Invoke(null);
          }
        }

      return _instance;
    }
  }
}

Buradaki T tekil oluşturulacak olan sınıfı temsil ediyor. Burada daha önce görmeye alışık olmadığımız bir keyword var o da volatile .volatile ile bildirilen değişkenler farklı iş parçacıkları yada prosesler tarafından ortak kullanılıyor olsa da programın akışı içerisinde her zaman son versiyonu elde edilecektir böylece olası hataların önüne geçilmiş olunur.

public static SingleInstanceClass Instance
{
  get
  {
    return Singleton<SingleInstanceClass>.Instance;
  }
}

Artık bu sınıfın bir nesnesine ihtiyaç duyduğunuzda  SingleInstanceClass.Instance şeklinde çağırıp sınıfın statik olmayan metodlarına erişebilirsiniz.

Peki bu kadar efora ne gerek var diyorsanız şunu aklınızdan çıkarmayın derim. Örneğin bir log yazan bir sınıfınız var ve static metodlarla text dosyaya log yazma işlemini yapabiliyorsunuz buraya kadar herşey güzel ancak daha sonra logları veritabanına yazmanız gerektiğinde bu sınıfı genişletemeyeceksiniz . Bu şekilde bir pattern kullandığınızda ise inheritance ile genişletebileceksiniz.

Basit örnek :

<code>public static class Logger {
    public static void Log(string s) { ... }
}

public class Client {
    public void DoSomething() {
        Logger.Log("DoSomething called");
    }
}</code>

Singleton pattern kullanılan örnek :

</pre>
 <code><code>public class Logger {
 private static Logger _instance;
 public static Logger Instance
 {
 get
 {
 if (_instance == null)
 _instance = new Logger();
 return _instance;
 }
 set { _instance = value; }
 }
 protected Logger() { }
 public virtual void Log(string s) { ... }
}</code></code>

public class Client {
 public void DoSomething() {
 Logger.Instance.Log("DoSomething called");
 }
 }
<pre>

TestLogger : Logger şeklinde yeni bir Logger türetilebilir.

Umarım makale size singleton patterni ve bunu nasıl generic hale getirebileceğiniz hakkında ufak da olsa bir fikir vermiştir.
Herkese iyi çalışmalar.

Kaynaklar :
http://www.codeproject.com/Articles/14026/Generic-Singleton-Pattern-using-Reflection-in-C
http://geekswithblogs.net/akraus1/articles/90803.aspx
http://www.yoda.arachsys.com/csharp/singleton.html
http://www.csharpnedir.com/articles/read/?filter=&author=&cat=cs&id=155&title=Kod%20Optimizasyonu%20ve

October 19, 2012 - Posted by | C#, Yazılım | , , , , , ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s