时间: 2016/11/15 18:10:02
单例模式是是常用经典十几种设计模式中最简单的。.NET中单例模式的实现也有很多种方式。下面我来介绍一下NopCommerce中单例模式实现。
我之前的文章就分析了一下nop中EngineContext的实现。EngineContext是把一个Web请求用Nop的EngineContext引擎上下文封装。里面提供了一个IEngine的单例对象的访问方式。
下面就是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 ///14 15 ///Provides access to the singleton instance of the Nop engine. 16 17 ///提供了访问单例实例Nop引擎 18 19 /// 20 21 public class EngineContext 22 23 { 24 25 #region Methods 26 27 28 29 /// 30 31 /// Initializes a static instance of the Nop factory. 32 33 /// 初始化静态Nop工厂的实例 34 35 /// 36 37 /// 创建一个新工厂实例,尽管工厂已经被初始化 38 39 [MethodImpl(MethodImplOptions.Synchronized)] 40 41 public static IEngine Initialize(bool forceRecreate) 42 43 { 44 45 if (Singleton .Instance == null || forceRecreate) 46 47 { 48 49 Singleton .Instance = new NopEngine(); 50 51 52 53 var config = ConfigurationManager.GetSection("NopConfig") as NopConfig; 54 55 Singleton .Instance.Initialize(config); 56 57 } 58 59 return Singleton .Instance; 60 61 } 62 63 64 65 /// 66 67 /// Sets the static engine instance to the supplied engine. Use this method to supply your own engine implementation. 68 69 /// 设置静态引擎实例提供的引擎, 70 71 /// 72 73 /// The engine to use. 74 75 /// Only use this method if you know what you''re doing. 76 77 public static void Replace(IEngine engine) 78 79 { 80 81 Singleton .Instance = engine; 82 83 } 84 85 86 87 #endregion 88 89 90 91 #region Properties 92 93 94 95 /// 96 97 /// Gets the singleton Nop engine used to access Nop services. 98 99 /// 100 101 public static IEngine Current 102 103 { 104 105 get 106 107 { 108 109 if (Singleton .Instance == null) 110 111 { 112 113 Initialize(false); 114 115 } 116 117 return Singleton .Instance; 118 119 } 120 121 } 122 123 124 125 #endregion 126 127 } 128 129 }
上面Initialize方法使用[MethodImpl(MethodImplOptions.Synchronized)]声明,就保证只能有一个线程访问,因为.NET的Web程序无论是WebForm还是mvc都在服务端都是多线程的。这样就标记只能有一个线程调用Initialize方法,也就保证了实例对象IEngine的在内存中只有一份。然后把单例实例对象的存储到类Singleton中。Singleton就像是一个对象容器,可以把许多单例实例对象存储在里面。
下面我们来看看实例Singleton的实现思路。
1 using System; 2 3 using System.Collections.Generic; 4 5 6 7 namespace Nop.Core.Infrastructure 8 9 { 10 11 ///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 /// 20 21 /// The type of object to store. 22 23 /// Access to the instance is not synchrnoized. 24 25 public class Singleton : Singleton 26 27 { 28 29 static T instance; 30 31 32 33 /// The singleton instance for the specified type T. Only one instance (at the time) of this object for each type of T. 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 /// 58 59 /// Provides a singleton list for a certain type. 60 61 /// 62 63 /// The type of list to store. 64 65 public class SingletonList : Singleton > 66 67 { 68 69 static SingletonList() 70 71 { 72 73 Singleton >.Instance = new List (); 74 75 } 76 77 78 79 /// The singleton instance for the specified type T. Only one instance (at the time) of this list for each type of T. 80 81 public new static IList Instance 82 83 { 84 85 get { return Singleton >.Instance; } 86 87 } 88 89 } 90 91 92 93 /// 94 95 /// Provides a singleton dictionary for a certain key and vlaue type. 96 97 /// 98 99 /// The type of key. 100 101 /// The type of value. 102 103 public class SingletonDictionary : Singleton > 104 105 { 106 107 static SingletonDictionary() 108 109 { 110 111 Singleton >.Instance = new Dictionary (); 112 113 } 114 115 116 117 /// The singleton instance for the specified type T. Only one instance (at the time) of this dictionary for each type of T. 118 119 public new static IDictionary Instance 120 121 { 122 123 get { return Singleton >.Instance; } 124 125 } 126 127 } 128 129 130 131 /// 132 133 /// Provides access to all "singletons" stored by . 134 135 /// 136 137 public class Singleton 138 139 { 140 141 static Singleton() 142 143 { 144 145 allSingletons = new Dictionary object>(); 146 147 } 148 149 150 151 static readonly IDictionary object> allSingletons; 152 153 154 155 /// Dictionary of type to singleton instances. 156 157 public static IDictionary object> AllSingletons 158 159 { 160 161 get { return allSingletons; } 162 163 } 164 165 } 166 167 }
Singleton类里面用一个Dictionary