18

I need to store a bunch of variables that need to be accessed globally and I'm wondering if a singleton pattern would be applicable. From the examples I've seen, a singleton pattern is just a static class that can't be inherited. But the examples I've seen are overly complex for my needs. What would be the very simplest singleton class? Couldn't I just make a static, sealed class with some variables inside?

cam
  • 8,095
  • 17
  • 54
  • 81
  • for discussion of more modern implementation see: http://stackoverflow.com/questions/2117241/is-implementing-a-singleton-using-an-auto-property-a-good-idea – Philm Sep 12 '18 at 14:25
  • and: https://stackoverflow.com/questions/32738283/auto-property-initializer-singleton-implementation?noredirect=1&lq=1 – Philm Sep 12 '18 at 14:30

8 Answers8

45

Typically a singleton isn't a static class - a singleton will give you a single instance of a class.

I don't know what examples you've seen, but usually the singleton pattern can be really simple in C#:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    static Singleton() {} // Make sure it's truly lazy
    private Singleton() {} // Prevent instantiation outside

    public static Singleton Instance { get { return instance; } }
}

That's not difficult.

The advantage of a singleton over static members is that the class can implement interfaces etc. Sometimes that's useful - but other times, static members would indeed do just as well. Additionally, it's usually easier to move from a singleton to a non-singleton later, e.g. passing in the singleton as a "configuration" object to dependency classes, rather than those dependency classes making direct static calls.

Personally I'd try to avoid using singletons where possible - they make testing harder, apart from anything else. They can occasionally be useful though.

Camilo Terevinto
  • 26,697
  • 6
  • 67
  • 99
Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • Awesome explanation....Can you tell us one instance (real time) where you would find singleton pattern useful? +1 – Raja Apr 19 '10 at 11:52
  • @Raja: I can't think of any genuine situations at the minute, although that doesn't mean I haven't used any. – Jon Skeet Apr 19 '10 at 11:59
  • @Raja this is something I'm going to use alot in .NET 4.0 in my classes that do any reflection `private static readonly ConcurrentDictionary _reflectionCache = new ConcurrentDictionary();` – Chris Marisic Apr 19 '10 at 12:44
  • I'm a relatively new programmer. I find myself using Singleton classes for accessing a database. Then from anywhere in my program I can call MyDB.AddRecord(...) where AddRecord is a static method that calls itself on the static instance. Especially for configuration databases it's nice to be able to call the database from wherever instead of passing an object around. This is just my newbie experience. What's your opinion on this approach? Am I setting myself up for a world of hurt down the road by doing this? Just wondering your $0.02USD – bufferz Apr 19 '10 at 13:48
  • 1
    @bufferz: That tends to make it harder to test things, IMO - you're wiring up everything to that one class, rather than presenting each object with its dependencies. – Jon Skeet Apr 19 '10 at 14:04
  • Compiling something similar to the above in VS2010, framework 3.5 SP1 yields `error CS0515: access modifiers are not allowed on static constructors` - presumably the `private` should not be included on the static constructor? (Or perhaps I'm missing something else...?) – SteveWilkinson Apr 12 '11 at 09:49
  • @Steve: Yes, the `private` shouldn't be there. Have corrected the typo. – Jon Skeet Apr 12 '11 at 09:57
  • @Raja Simple singleton blank for .NET: http://ilyatereschuk.blogspot.com/2013/12/c-simple-singleton-blank-for-everyday.html –  Dec 24 '13 at 06:56
  • @IlyaTereschuk: I see someone's already left a comment on your blog referring to my article - I don't view double-checked locking as "simple" compared with using a type initializer (or `Lazy`) – Jon Skeet Dec 24 '13 at 09:50
  • 1
    @JonSkeet I can't believe Jon Skeet replying me :). Thanks, i'll check it out –  Dec 24 '13 at 11:10
  • Can some one please elaborate this statement. `static contrcutor: Make sure it's truly lazy` – Unbreakable Sep 05 '18 at 20:51
  • @Unbreakable: See http://csharpindepth.com/Articles/General/Beforefieldinit.aspx – Jon Skeet Sep 06 '18 at 06:21
  • I thought about a new question, but I thought it is better to add it to this epic thread: Wouldn´t it be equivalent and easier understandable to have not empty static constructor, but put the initialization there? "new Singleton();" At least it is cleaner to read for me. Inits in a ctor if not trivial, should be slighly preferred as more explicit, IMHO. Concerning all explanations in csharpindepth about it, this question seems not clearly answered. From which I understand, the two should be equivalent. – Philm Sep 12 '18 at 14:00
  • Is there any difference in replacing the Property with computed property: `public static Singleton Instance => instance` – Philm Sep 12 '18 at 14:09
  • @Philm: No, that's *exactly* the same. These days I'd probably make it an automatically-implemented read-only property in fact. – Jon Skeet Sep 12 '18 at 14:10
8

There are several Patterns which might be appropriate for you, a singleton is one of the worse.

Registry

struct Data {
  public String ProgramName;
  public String Parameters;
}

class FooRegistry {
  private static Dictionary<String, Data> registry = new Dictionary<String, Data>();
  public static void Register(String key, Data data) {
     FooRegistry.registry[key] = data;
  }
  public static void Get(String key) {
     // Omitted: Check if key exists
     return FooRegistry.registry[key];
  }
}

Advantages

  • Easy to switch to a Mock Object for automated testing
  • You can still store multiple instances but if necessary you have only one instance.

Disadvantages

  • Slightly slower than a Singleton or a global Variable

Static Class

class GlobalStuff {
  public static String ProgramName {get;set;}
  public static String Parameters {get;set;}
  private GlobalStuff() {}
}

Advantages

  • Simple
  • Fast

Disadvantages

  • Hard to switch dynamically to i.e. a Mock Object
  • Hard to switch to another object type if requirements change

Simple Singleton

class DataSingleton {
  private static DataSingleton instance = null;
  private DataSingleton() {}
  public static DataSingleton Instance {
     get {
         if (DataSingleton.instance == null) DataSingleton.instance = new DataSingleton();
         return DataSingleton;
     }
  }
}

Advantages

  • None really

Disadvantages

  • Hard to create a threadsafe singleton, the above Version will fail if multiple threads access the instance.
  • Hard to switch for a mock object

Personally I like the Registry Pattern but YMMV.

You should take a look at Dependency Injection as it's usually considered the best practice but it's too big a topic to explain here:

Dependency Injection

Dean Meehan
  • 2,321
  • 17
  • 33
Morfildur
  • 12,196
  • 6
  • 32
  • 54
  • I think your singleton pattern is wrong, that if check inside of the getter isn't thread safe. You want to implement a singleton the as described above by @Jon Skeet. Theoretically 2 threads could enter that getter at the same time both see instance == null and then both execute the 2nd line causing the singleton to mutate by the last out thread. – Chris Marisic Apr 19 '10 at 12:44
  • @Chris: I mentioned that this implementation is not threadsafe in the "Disadvantages" section. The Code is there to explain the concept, not to give a fully working example. – Morfildur Apr 19 '10 at 12:46
  • @dbemerlin please fix code for FooRegistry, public static **Data** Get(String key) instead of _void_ . And really thanks for nice overview. – Aleksey Dr. Jun 20 '16 at 17:05
4

A Singleton isn't just a static class that can't be inherited. It's a regular class that can be instantiated only once, with everybody sharing that single instance (and making it thread safe is even more work).

The typical .NET code for a Singleton looks something like the following. This is a quick example, and not by any means the best implementation or thread-safe code:

public sealed class Singleton
{
    Singleton _instance = null;

    public Singleton Instance
    {
        get
        {
            if(_instance == null)
                _instance = new Singleton();

            return _instance;
        }
    }

    // Default private constructor so only we can instanctiate
    private Singleton() { }

    // Default private static constructor
    private static Singleton() { }
}

If you're going to go down the path you're thinking, a static sealed class will work just fine.

Justin Niessner
  • 229,755
  • 35
  • 391
  • 521
  • I think you need to revise that code somewhat - and unless you're careful in the revision, it won't be thread-safe. However, making it thread-safe is really pretty easy. – Jon Skeet Apr 19 '10 at 12:00
  • @Jon I wasn't going for the thread-safe version here. Quick example. I know one way to make it thread-safe, but I'd be interested to know the other revisions (just out of curiosity). – Justin Niessner Apr 19 '10 at 12:19
3

Using C# 6 Auto-Property Initializers.

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

Short and clean - I'll be happy to hear the downsides.

chenop
  • 3,486
  • 2
  • 34
  • 51
0

I know this Issue is old, but here is another solution using .Net 4.0 or later (including .Net Core and .Net Standard).

First, define your class that will be transformed into a Singleton:

public class ClassThatWillBeASingleton
{
    private ClassThatWillBeASingleton()
    {
        Thread.Sleep(20);
        guid = Guid.NewGuid();
        Thread.Sleep(20);
    }

    public Guid guid { get; set; }
}

In this Example Class I've defined one constructor that Sleeps for a while, and then creates one new Guid and save to it's public property. (The Sleep is just for concurrency testing)

Notice that the constructor is private, so that no one can create a new instance of this class.

Now, We need to define the wrapper that will transform this class into a singleton:

public abstract class SingletonBase<T> where T : class
{
    private static readonly Lazy<T> _Lazy = new Lazy<T>(() =>
    {
        // Get non-public constructors for T.
        var ctors = typeof(T).GetConstructors(System.Reflection.BindingFlags.Instance |
                                              System.Reflection.BindingFlags.NonPublic);
        if (!Array.Exists(ctors, (ci) => ci.GetParameters().Length == 0))
            throw new InvalidOperationException("Non-public ctor() was not found.");
        var ctor = Array.Find(ctors, (ci) => ci.GetParameters().Length == 0);
        // Invoke constructor and return resulting object.
        return ctor.Invoke(new object[] { }) as T;
    }, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);

    public static T Instance
    {
        get { return _Lazy.Value; }
    }
}

Notice that it uses Lazy to create a field _Lazy that knows how to instantiate a class using it's private constructor.

And it defines one Property Instance to access the Value of the Lazy field.

Notice the LazyThreadSafetyMode enum that is passed to the Lazy constructor. It is using ExecutionAndPublication. So only one thread will be allowed to initialize the Value of the Lazy field.

Now, all we have to do is define the wrapped class that will be a singleton:

public class ExampleSingleton : SingletonBase<ClassThatWillBeASingleton>
{
    private ExampleSingleton () { }
}

Here is one example of the usage:

ExampleSingleton.Instance.guid;

And one test to assert that two threads will get the same instance of the Singleton:

[Fact()]
public void Instance_ParallelGuid_ExpectedReturnSameGuid()
{
    Guid firstGuid = Guid.Empty;
    Guid secondGuid = Guid.NewGuid();

    Parallel.Invoke(() =>
    {
        firstGuid = Singleton4Tests.Instance.guid;
    }, () =>
    {
        secondGuid = Singleton4Tests.Instance.guid;
    });

    Assert.Equal(firstGuid, secondGuid);
}

This test is calling the Value of the Lazy field concurrently, and we want to assert that both instances that will be returned from this property (Value of Lazy) are the same.

More details about this subject can be found at: C# in Depth

-1

So, as far as I am concerned, this is the most concise and simple implementation of the Singleton pattern in C#.

http://blueonionsoftware.com/blog.aspx?p=c6e72c38-2839-4696-990a-3fbf9b2b0ba4

I would, however, suggest that singletons are really ugly patterns... I consider them to be an anti-pattern.

http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx

For me, I prefer to have something like a Repository, implementing IRepository. Your class can declare the dependency to IRepository in the constructor and it can be passed in using Dependency Injection or one of these methods:

http://houseofbilz.com/archive/2009/05/02.aspx

Brian Genisio
  • 46,643
  • 16
  • 121
  • 163
-1

Use your language features. Mostly simple thread-safe implementation is:

public sealed class Singleton
{
    private static readonly Singleton _instance;

    private Singleton() { }

    static Singleton()
    {
        _instance = new Singleton();
    }

    public static Singleton Instance
    {
        get { return _instance; }
    }
}
ZOXEXIVO
  • 833
  • 9
  • 19
-1

...what would be the very simplest singleton class?

Just to add one more possible solution. The simplest, most straight forward and easy to use approach I can think of would be something like this:

//The abstract singleton
public abstract class Singleton<T> where T : class
{
    private static readonly Lazy<T> instance = new Lazy<T>( CreateInstance, true );

    public static T Instance => instance.Value;

    private static T CreateInstance()
    {
        return (T)Activator.CreateInstance( typeof(T), true);
    }
}

//This is the usage for any class, that should be a singleton
public class MyClass : Singleton<MyClass>
{
    private MyClass()
    {
        //Code...
    }

    //Code...
}

//Example usage of the Singleton
class Program
{
    static void Main(string[] args)
    {
        MyClass clazz = MyClass.Instance;
    }
}
MikeVe
  • 762
  • 5
  • 12
  • Those classes aren't singletons. Any number of instances of them can be created as there is a public constructor. – Servy Apr 11 '18 at 17:45
  • Well sure. Any Subclass of Singleton that has a public constructor besides the private one won't be a singleton. The above approach does not enforce singletons. – MikeVe Apr 11 '18 at 18:10