A brief reference on ways to implement the singleton pattern.
Static Class
Use a static class for your singleton only in the most basic of applications.
Here is an example of using a static class for a threadsafe collection of objects that you want to access from anywhere in your application:
public static class MyGlobalCollection
{
public static readonly ConcurrentBag<object> _stuff = new ConcurrentBag<object>();
}
Non-Static Class
Using a non-static class allows you to do more with your singleton, including:
- Implement interfaces (IDisposable is often an important one)
- Pass it as a parameter into code from other libraries
- Swap out instances of your singleton instance at runtime
- Run unit tests in parallel without stepping on each other
- Use it as a template object to be cloned
- Serialize the instance
With this method, the class of your singleton object manages the instance itself, ensuring that there is only one instance.
Example:
public class MyConnectionFactory
{
private static MyConnectionFactory _instance;
private MyConnectionFactory() { }
public static MyConnectionFactory Instance()
{
if (_instance == null)
_instance = new MyConnectionFactory();
return _instance;
}
}
A real example is NLog.Config.ConfigurationItemFactory
Dependency-Injection
A Dependency Injection container can be used to manage a singleton.
In the ConfigureServices() method of Startup.cs, you simply tell it to manage a singleton instance:
services.AddSingleton<IMySingletonService, MySingletonService>();
You can read more about using dependency injection and singletons in ASP.NET Core here.
Leave a Reply