首页 > 代码库 > 【NopCommerce源码架构学习-二】单例模式实现代码分析

【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 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的实现思路。

二、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> Instance
120 
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 Singleton
138 
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> AllSingletons
158 
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>。

【NopCommerce源码架构学习-二】单例模式实现代码分析