Skip to content

Singleton

Stanislav Osipov edited this page Oct 17, 2020 · 1 revision

I bet you can find a lot of info about that pattern. But short summary of what it does:

  • Ensure a class has only one instance, and provide a global point of access to it.
  • Encapsulated "just-in-time initialization" or "initialization on first use".

Before using it be aware of possible pitfalls. Here is a small highlight from stackoverflow:

Singleton is generally a bad idea if you are doing unit testing, and its generally a bad idea not to do unit testing (or BDD or Acceptance Testing).

Making objects have global state means that the unit tests you write involving these objects will be isolated and disjoint from one another. Instead, you will have to worry about resetting the state for each test and believe me ... that is never done 100% of the time. If you don't reset the global state then you start to get very weird and hard to debug errors in your tests that waste time.

Global state also increases coupling in your code and makes it very hard to refactor.

The ideal method would be to use an IoC/DI container (Spring, Guice, etc.) to request objects. These containers often have ways of making objects appear as 'Singletons' but they also have ways of modifying that behavior depending on the situation (i.e. unit testing vs. your domain code).

This all depends on the size of your problem of course. If you're hacking together a 4-class test rig to try something out then go ahead and use a Singleton. However, as soon as that project takes on life and grows bigger and more complex then refactor the Singleton out.

Singleton

The Singleton is a simple not related to unity C# implementation of this pattern.

The usage is super simple.

  1. Declare your Singleton Type.
public class MySingleton : Singleton<MySingleton>
{
    public string HelloWorld => "Hello World";
}
  1. Use from anywhere:
var hello = MySingleton.Instance.HelloWorld;

MonoSingleton

The MonoSingleton pattern designed to be used for types extended from a MonoBehaviour

The usage is absolutely the same:

public class MySingleton : MonoSingleton<MySingleton>
{
    public string HelloWorld => "Hello World";
}
var hello = MySingleton.Instance.HelloWorld;

The only difference is:

  • In this case MySingleton is a MonoBehaviour and can be placed on GameObject
  • The GameObject will be marked as (DontDestroyOnLoad)[https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html]
  • If an object wasn't placed on GameObject before an attempt to access Instance property the new GameObject will be created with MySingleton type attached.