4

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.

probably at the beach
  • 14,489
  • 16
  • 75
  • 116
  • 1
    what you mean reuse? implement other singletons? – Sergey Vedernikov Mar 03 '11 at 11:08
  • 2
    When looking at that page, did you note that the 4th/5th versions are preferred? This is the 2nd version... In particular with the 4th version there is so little code that it simply doesn't hurt to duplicate it. – Marc Gravell Mar 03 '11 at 11:08
  • 2
    Highly related: http://stackoverflow.com/questions/380755/a-generic-singleton – cwap Mar 03 '11 at 11:08
  • 1
    @cwap @tokk which is complete rubbish; a "generic singleton" makes none of the **essential** guarantees to make it a singleton. That is just a "generic static default instance" - not the same – Marc Gravell Mar 03 '11 at 11:10
  • Mmh, maybe singleton could become a VS snippet... also, it wouldn't so hard to write... – digEmAll Mar 03 '11 at 11:12
  • 2
    @dig, programmers should shoot themselves that day when Singletone will become a snippet. Use IoC, get rid of singletons written in this way. – Snowbear Mar 03 '11 at 11:14
  • @Marc yes I did and deliberately chose number 2. Number 5 is about 15 lines of code. I have to implement 20 of these which is another 300 lines of code I'd rather not look after. – probably at the beach Mar 03 '11 at 11:17
  • @Snowbear: I agree, I tend to avoid using singletons... Mine, was just a consideration ;) – digEmAll Mar 03 '11 at 11:19
  • Worth mentioning that Microsoft's own solution is here http://msdn.microsoft.com/en-us/library/ff650316.aspx with reasoning. Is solution 3 from page linked in the question. – Jim Grimmett Oct 03 '12 at 12:20

5 Answers5

5

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()
    {
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks for your answer Jon but I don't want them all initialised when the code first runs which happens in method 5. Method 2 provides more control in that area. – probably at the beach Mar 03 '11 at 11:23
  • 1
    @Richard: Don't forget it'll only run this when *this type* is first used. Are you really using the rest of the type without using an instance of it? – Jon Skeet Mar 03 '11 at 11:37
  • @Guillaume: The page that was referenced in the question. – Jon Skeet Mar 03 '11 at 11:38
3
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();
Tokk
  • 4,499
  • 2
  • 31
  • 47
  • I don't think that is what he wanted, but is close – mike Mar 03 '11 at 11:13
  • 2
    At that point, `YourClass` has to have a public parameterless constructor, which means it's not really a singleton. – Jon Skeet Mar 03 '11 at 11:13
  • it should be "static T instance=default(T);" or "public static class Singleton where T:class,new()" to avoid errors – PVitt Mar 03 '11 at 11:14
2

Try take a look at: http://www.codeproject.com/KB/architecture/GenericSingletonPattern.aspx

70sCommander
  • 958
  • 1
  • 8
  • 16
2

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;
        }
    }
}
}
Massif
  • 4,327
  • 23
  • 25
1

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();
  }
}
mike
  • 3,146
  • 5
  • 32
  • 46