probably at the beach
probably at the beach

Reputation: 15227

c# singleton code reuse

I have a number of classes doing different things but using the same Singleton pattern from http://www.yoda.arachsys.com/csharp/singleton.html

public sealed class Singleton
{
static Singleton instance=null;
static readonly object padlock = new object();

Singleton()
{
}

public static Singleton Instance
{
    get
    {
        lock (padlock)
        {
            if (instance==null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}
}

Does anyone have a neat way I can reuse as much of the common Singleton code as possible between the different classes?

For example if I have SingletonJob1 and SingletonJob2 I'd like to be able to change the code in only place if I move to one of the other Singleton patterns.

Edit: Yes as people have pointed out Method 5 from http://www.yoda.arachsys.com/csharp/singleton.html is less code. I did read to the end of the page! I chose method 2 because the Singleton objects relate to hardware devices and I want only want a couple of them initialised and used in any given run of the program. Method 5 will initialise them all straight away.

Upvotes: 4

Views: 1640

Answers (5)

Jon Skeet
Jon Skeet

Reputation: 1503290

Is there any reason you're using that version rather than the simpler one which just initializes the instance in the declaration?

public class Singleton
{
    private static Singleton instance = new Singleton();
    public static Singleton Instance { get { return instance; } }

    // Only use this if you really need it - see the page for details
    static Singleton() {}

    private Singleton()
    {
        // I assume this logic varies
    }
}

This pattern is sufficiently short that I don't think it's much of a problem to include it everywhere.

I would urge you to consider whether you really need that many singletons; they're generally not great for testability etc.

EDIT: If you really, really want laziness and you're using .NET 4, you can get it with the 6th pattern which is on the singleton page's new home:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

Upvotes: 5

mike
mike

Reputation: 3166

I believe this is what you are after. However I strongly recommend avoiding this Singleton (capital S) pattern as it crushes all unit testing souls and makes heaps of things difficult to control.

public class Singleton<T> where T : new()
{
  private static T _Instance;
  private static readonly object _InstanceLock = new object();

  public static T Instance
  {
    get
    {
      if (_Instance == null)
      {
        lock (_InstanceLock)
        {
          if (_Instance == null)
          {
            _Instance = new T();
          }
        }
      }
      return _Instance;
    }
  }

}

public class Foo : Singleton<Foo>
{
  public void Something()
  {
  }
}

public class Example
{
  public static void Main()
  {
    Foo.Instance.Something();
  }
}

Upvotes: 1

Massif
Massif

Reputation: 4433

Something like this?

public sealed class Singleton<T>
{
static T instance=null;
static readonly object padlock = new object();
static Func<T> createInstance;

Singleton(Func<T> constructor)
{
   createInstance = constructor;
}

public static T Instance
{
    get
    {
        lock (padlock)
        {
            if (instance==null)
            {
                instance = createInstance();
            }
            return instance;
        }
    }
}
}

Upvotes: 2

Tokk
Tokk

Reputation: 4502

public static class Singleton<T>  where T: new()
{

static T instance=null;
static readonly object padlock = new object();

public static T Instance
{
    get
    {
        lock (padlock)
        {
            if (instance==null)
            {
                instance = new T();
            }
            return instance;
        }
    }
}

}

So you can use your Singleton for all Classes:

Singleton<YourClass>.Instance.YourMethod();

Upvotes: 3

Related Questions