Ha ha, I come, I come again, in this close to the time, while there is time, I will learn and review the old knowledge. In.NET Core development, we will often use injection to inject a singleton class, but in most cases without injection, we will implement a singleton class ourselves or, more simply, a static class. They are often used for a specific purpose, but what is the difference between them?

1. Design pattern: singleton pattern

Singleton: A pattern that belongs to the type of pattern created in the design pattern. Classes created through the singleton method have only one instance in the current program and can of course be implemented as thread-safe singleton.

Here’s a quick review of the creation code:

1.1 Distribution upon use,

Instantiation when used, when multi-threaded applications, improper use will have thread safety issues.

public class SingletonA
    {
        // Private member that allocates memory when used
        private static SingletonA _instance = null;
        // Private construct, eliminate direct new class
        private SingletonA(){}// Get the instance
        public static SingletonA GetInstance ()
        { 

            if (_instance == null)
            {
                _instance = new SingletonA();
            }
            return_instance; }}Copy the code

1.2 Instantiation during declaration

Instantiation when the instance is declared, and when multi-threaded applications are used improperly, there will be thread safety issues.

 public class SingletonB
    {
        // Private static member, assigned when class instance is declared
        private static readonly SingletonB _instance = new SingletonB();
        // Private construct, eliminate direct new class
        private SingletonB(){}public static SingletonB GetInstance()
        {            
            return_instance; }}Copy the code

1.3 double check the lock

Recommend this, the classic thread-safe singleton implementation

public class SingletonD
    {
        private static SingletonD _instance = null;
        private static readonly object _lockObject = new object(a);private SingletonD(){}public static SingletonD GetInstance()
        {
            if (_instance == null)
            {
                lock (_lockObject)
                {
                    if (_instance == null)
                        _instance = newSingletonD(); }}return_instance; }}Copy the code

1.4. Net features ensure thread safety

The most compact edition

public sealed class SingletonC
    {
        private SingletonC(){}public static readonly SingletonC Instance = new SingletonC();
    }

Copy the code

1.5 Implementation when DI is used

//FileLogger should be defined as a generic class, not a singleton, and certainly not a static class. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton<ILogger, FileLogger>(); }Copy the code

2. Comparison of singleton classes and static classes

The comparison is based on the following points

  • Whether dependency injection is supported
  • What about memory management
  • scalability
  • testability

The static class looks like:

public static class StaticExample
    {
        private static readonly object lockObj = new object(a);public static void Log(string message)
        {
            //Write code here to log data.}}Copy the code
Features comparison Static class Singleton class
Whether dependency injection is supported If no, compile time prompts that static types cannot be used as type parameters support
What about memory management Static classes are stored in the high Frequency heap of the managed heap, and memory is released only when the application is unloaded A single instance of a singleton class is static and therefore also stored in the high Frequency heap, where memory is released when the application is unloaded. However, unlike static classes, which can only have static objects, singleton classes can have both static and non-static objects. Therefore, from a memory management perspective, you can leverage garbage collection management objects when using singleton classes.
scalability You cannot inherit a static class and override its methods; Static classes cannot have extension methods A singleton class typically contains a private constructor and is marked sealed to indicate that it can neither be instantiated nor inherited; Therefore, you can extend a singleton class only if it has a non-private constructor in it; A singleton class can have extension methods
testability Simulating static classes is very difficult, especially when static objects are included. Of course, if you only have static methods and are idempotent, it’s easy to test Testing a singleton class is easy

3. Application scenarios

From the above comparisons, you get the idea.

Static classes are a good choice when you only need a utility class that contains multiple methods, in which case you don’t need an instance. Because you don’t have any instances of this class, this simple implementation improves the performance of your application.

The singleton pattern can be used to design classes that require only one instance. Typical examples include manager classes for logging, caching, thread pools, etc. In these scenarios, singleton classes are a good choice. To do this, you should have an instance to avoid conflicting requests for the same resource. Also, with the introduction of the DI framework, you should make more use of singleton classes, as it is simply necessary to define a common class and register it with DI.

Of course, the singleton class is more like object-oriented programming