單例模式是是常用經典十幾種設計模式中最簡單的。.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 /// <summary> 14 15 ///Provides access to the singleton instance of the Nop engine. 16 17 ///提供了訪問單例實例Nop引擎 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 /// 初始化靜態Nop工廠的實例 34 35 /// </summary> 36 37 /// <param name="forceRecreate">創建一個新工廠實例,盡管工廠已經被初始化</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 /// 設置靜態引擎實例提供的引擎, 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 Current 102 103 { 104 105 get 106 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 #endregion 126 127 } 128 129 }
上面Initialize方法使用[MethodImpl(MethodImplOptions.Synchronized)]聲明,就保證只能有一個線程訪問,因為.NET的Web程序無論是WebForm還是mvc都在服務端都是多線程的。這樣就標記只能有一個線程調用Initialize方法,也就保證了實例對象IEngine的在內存中只有一份。然後把單例實例對象的存儲到類Singleton中。Singleton就像是一個對象容器,可以把許多單例實例對象存儲在裡面。
下面我們來看看實例Singleton的實現思路。