你的位置:首页 > ASP.net教程

[ASP.net教程]【NopCommerce源码架构学习


单例模式是是常用经典十几种设计模式中最简单的。.NET中单例模式的实现也有很多种方式。下面我来介绍一下NopCommerce中单例模式实现。

我之前的文章就分析了一下nop中EngineContext的实现。EngineContext是把一个Web请求用Nop的EngineContext引擎上下文封装。里面提供了一个IEngine的单例对象的访问方式。

下面就是EngineContext的源码:

一、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 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 }

 

上面Initialize方法使用[MethodImpl(MethodImplOptions.Synchronized)]声明,就保证只能有一个线程访问,因为.NET的Web程序无论是WebForm还是mvc都在服务端都是多线程的。这样就标记只能有一个线程调用Initialize方法,也就保证了实例对象IEngine的在内存中只有一份。然后把单例实例对象的存储到类Singleton中。Singleton就像是一个对象容器,可以把许多单例实例对象存储在里面。

下面我们来看看实例Singleton的实现思路。

二、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 }

 

Singleton类里面用一个Dictionary<Type, object>()集合来存储所有的单例对象。基于Singleton类创建一些泛型类Singleton<T>,Singleton<IList<T>>,SingletonList<T>,Singleton<IDictionary<TKey, TValue>>和SingletonDictionary<TKey, TValue>。