Thứ Năm, 18 tháng 7, 2013

Singleton when multiple user access

Only providing one user access to a resource is not the purpose of a Singleton.  The Singleton pattern allows multiple users to share a single object.  

For example, say you had a complex program with many forms, but wanted your program to share a single data connection to a shared resource, so you weren't opening many connections.  You could use a singleton to allow every form within the application to access the same "Repository" instance for data.  In this case, a singleton would be a good option.

If you want to prevent multiple instances from using the same resource at the same time, you could modify your class to include some manual resource locking, preventing multiple simultaneous instances.  Here's an example:
using System;

public sealed class Singleton
{
    private class DispsoseHandle : IDisposable
    {
        public void Dispose()
         {
             lock(Singleton.lockObj)
             {
                 Singleton.available = true;
             }
         }
    }

    private static readonly Singleton sharedInstance = new Singleton();
    private static readonly object lockObj = new object();
    private static bool available = true;

    private Singleton()
    {
    }

    public IDisposable ResourceHandle
    {
        get
        {
            return new DispsoseHandle();
        }
    }

    // use a method instead, here
    public static bool TryGetInstance(out Singleton instance)
    {
        lock (lockObj)
        {
            if (available)
            {
                available = false;
                instance = sharedInstance;
                return true;
            }
            else
            {
                instance = null;
                return false;
            }
        }
    }
}
class Program 
{
        static void Main(string[] args)
        {
            Singleton instance;
            if (Singleton.TryGetInstance(out instance))
            {
                using (instance.ResourceHandle)
                {
                    // Do something with the singleton instance
                }
            }

            Console.ReadKey();
        }

}

Không có nhận xét nào: