[NopCommerce source code architecture learning-2] Code Analysis in singleton mode, nopcommerce source code
The Singleton mode is the simplest of more than a dozen typical design patterns .. There are also many ways to implement the singleton mode in. NET. Next I will introduce the implementation of the single-sample mode in NopCommerce.
My previous article analyzed the implementation of EngineContext in nop. EngineContext encapsulates a Web request in the context of the EngineContext engine of Nop. It provides an IEngine singleton object access method.
The following is the source code of EngineContext:
1. EngineContext
1 using System. configuration; 2 3 using System. runtime. compilerServices; 4 5 using Nop. core. configuration; 6 7 8 9 namespace Nop. core. infrastructure 10 11 {12 13 // <summary> 14 15 // Provides access to the singleton instance of the Nop engine. 16 17 // provide access to the singleton instance Nop Engine 18 19 /// </summary> 20 21 public class EngineContext 22 23 {24 25 # region Methods 26 27 28 29/ // <summary> 30 31 // Initializes a static instance of the Nop factory. 32 33 // initialize the instance 34 35 of the static Nop factory /// </summary> 36 37 /// <param name = "forceRecreate"> Create a new factory instance, although the factory has been initialized </param> 38 39 [MethodImpl (MethodImplOptions. synchronized)] 40 41 public static IEngine Initialize (bool forceRecreate) 42 43 {44 45 if (Singleton <IEngine>. instance = null | forceRecreate) 46 47 {48 49 Singleton <IEngine>. instance = new NopEngine (); 50 51 52 53 var config = ConfigurationManager. getSection ("NopConfig") as NopConfig; 54 55 Singleton <IEngine>. instance. initialize (config); 56 57} 58 59 return Singleton <IEngine>. instance; 60 61} 62 63 64 65 // <summary> 66 67 // Sets the static engine instance to the supplied engine. use this method to supply your own engine implementation. 68 69 // set The engine provided by The static engine instance, 70 71 /// </summary> 72 73 // <param name = "engine"> The engine to use. </param> 74 75 // <remarks> Only use this method if you know what you're doing. </remarks> 76 77 public static void Replace (IEngine engine) 78 79 {80 81 Singleton <IEngine>. instance = engine; 82 83} 84 85 86 87 # endregion 88 89 90 91 # region Properties 92 93 94 95 // <summary> 96 97 // Gets the singleton Nop engine used to access Nop services. 98 99 // </summary> 100 101 public static IEngine Current102 103 {104 105 get106 107 {108 109 if (Singleton <IEngine>. instance = null) 110 111 {112 113 Initialize (false); 114 115} 116 117 return Singleton <IEngine>. instance; 118 119} 120 121} 122 123 124 125 # endregion126 127} 128 129}
The above Initialize method uses the [MethodImpl (MethodImplOptions. Synchronized)] Declaration to ensure that only one thread can be accessed, because. NET Web programs, whether WebForm or mvc, are multithreading on the server side. In this way, only one thread can call the Initialize method, which ensures that the Instance Object IEngine has only one copy in the memory. Then, the Singleton class is stored as a Singleton instance object. Singleton is like an object container, which can store many Singleton instance objects.
Let's take a look at the implementation of Singleton.
Ii. Singleton
1 using System; 2 3 using System.Collections.Generic; 4 5 6 7 namespace Nop.Core.Infrastructure 8 9 { 10 11 /// <summary> 12 13 /// A statically compiled "singleton" used to store objects throughout the 14 15 /// lifetime of the app domain. Not so much singleton in the pattern's 16 17 /// sense of the word as a standardized way to store single instances. 18 19 /// </summary> 20 21 /// <typeparam name="T">The type of object to store.</typeparam> 22 23 /// <remarks>Access to the instance is not synchrnoized.</remarks> 24 25 public class Singleton<T> : Singleton 26 27 { 28 29 static T instance; 30 31 32 33 /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this object for each type of T.</summary> 34 35 public static T Instance 36 37 { 38 39 get { return instance; } 40 41 set 42 43 { 44 45 instance = value; 46 47 AllSingletons[typeof(T)] = value; 48 49 } 50 51 } 52 53 } 54 55 56 57 /// <summary> 58 59 /// Provides a singleton list for a certain type. 60 61 /// </summary> 62 63 /// <typeparam name="T">The type of list to store.</typeparam> 64 65 public class SingletonList<T> : Singleton<IList<T>> 66 67 { 68 69 static SingletonList() 70 71 { 72 73 Singleton<IList<T>>.Instance = new List<T>(); 74 75 } 76 77 78 79 /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this list for each type of T.</summary> 80 81 public new static IList<T> Instance 82 83 { 84 85 get { return Singleton<IList<T>>.Instance; } 86 87 } 88 89 } 90 91 92 93 /// <summary> 94 95 /// Provides a singleton dictionary for a certain key and vlaue type. 96 97 /// </summary> 98 99 /// <typeparam name="TKey">The type of key.</typeparam>100 101 /// <typeparam name="TValue">The type of value.</typeparam>102 103 public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>>104 105 {106 107 static SingletonDictionary()108 109 {110 111 Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>();112 113 }114 115 116 117 /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this dictionary for each type of T.</summary>118 119 public new static IDictionary<TKey, TValue> Instance120 121 {122 123 get { return Singleton<Dictionary<TKey, TValue>>.Instance; }124 125 }126 127 }128 129 130 131 /// <summary>132 133 /// Provides access to all "singletons" stored by <see cref="Singleton{T}"/>.134 135 /// </summary>136 137 public class Singleton138 139 {140 141 static Singleton()142 143 {144 145 allSingletons = new Dictionary<Type, object>();146 147 }148 149 150 151 static readonly IDictionary<Type, object> allSingletons;152 153 154 155 /// <summary>Dictionary of type to singleton instances.</summary>156 157 public static IDictionary<Type, object> AllSingletons158 159 {160 161 get { return allSingletons; }162 163 }164 165 }166 167 }
The Singleton class uses a Dictionary <Type, object> () set to store all Singleton objects. Create some generic classes such as Singleton, Singleton, SingletonList, Singleton, and Singleton Based on the Singleton class, TValue>.