文章目录
概述
NopCommerce源码架构详解-单例模式实现源码分析。
内容
单例模式是23种常用设计模式中最简单的设计模式之一。.NET中单例模式的实现也有很多种方式。下面我来介绍一下NopCommerce中单例模式实现。
我之前的文章就分析了一下nop中EngineContext的实现。EngineContext是把一个Web请求用Nop的EngineContext引擎上下文封装。里面提供了一个IEngine的单例对象的访问方式。
下面就是EngineContext的源码:
1、EngineContext
using System; using System.Configuration; using System.Runtime.CompilerServices; using Nop.Core.Configuration; namespace Nop.Core.Infrastructure { public class EngineContext { #region Utilities /// <summary> /// 通过配置信息创建一个相应IEngine实例 /// </summary> /// <param name="config">Config</param> /// <returns>New engine instance</returns> protected static IEngine CreateEngineInstance(NopConfig config) { if (config != null && !string.IsNullOrEmpty(config.EngineType)) { var engineType = Type.GetType(config.EngineType); if (engineType == null) throw new ConfigurationErrorsException("The type '" + config.EngineType + "' could not be found. Please check the configuration at /configuration/nop/engine[@engineType] or check for missing assemblies."); if (!typeof(IEngine).IsAssignableFrom(engineType)) throw new ConfigurationErrorsException("The type '" + engineType + "' doesn't implement 'Nop.Core.Infrastructure.IEngine' and cannot be configured in /configuration/nop/engine[@engineType] for that purpose."); return Activator.CreateInstance(engineType) as IEngine; } return new NopEngine(); } #endregion #region Methods /// <summary> /// Initializes a static instance of the Nop factory.初始化创建一个IEngine的实例 /// </summary> /// <param name="forceRecreate">Creates a new factory instance even though the factory has been previously initialized.</param> [MethodImpl(MethodImplOptions.Synchronized)] public static IEngine Initialize(bool forceRecreate) { if (Singleton<IEngine>.Instance == null || forceRecreate) { var config = ConfigurationManager.GetSection("NopConfig") as NopConfig; Singleton<IEngine>.Instance = CreateEngineInstance(config); Singleton<IEngine>.Instance.Initialize(config); } return Singleton<IEngine>.Instance; } /// <summary> /// 替换单例中的实例对象 /// </summary> /// <param name="engine">The engine to use.</param> /// <remarks>Only use this method if you know what you're doing.</remarks> public static void Replace(IEngine engine) { Singleton<IEngine>.Instance = engine; } #endregion /// <summary> /// 获取IEngine单例实例对象 /// </summary> public static IEngine Current { get { if (Singleton<IEngine>.Instance == null) { Initialize(false); } return Singleton<IEngine>.Instance; } } } }
上面Initialize方法使用MethodImpl声明,就保证只能有一个线程访问,因为.NET的Web程序无论是WebForm还是mvc都在服务端都是多线程的。这样就标记只能有一个线程调用Initialize方法,也就保证了实例对象IEngine的在内存中只有一份。然后把单例实例对象的存储到类Singleton中。Singleton就像是一个对象容器,可以把许多单例实例对象存储在里面。
下面我们来看看实例Singleton的实现思路。
2、Singleton
ng System; using System.Collections.Generic; namespace Nop.Core.Infrastructure { public class Singleton<T> : Singleton { static T instance; public static T Instance { get { return instance; } set { instance = value; AllSingletons[typeof(T)] = value; } } } public class SingletonList<T> : Singleton<IList<T>> { static SingletonList() { Singleton<IList<T>>.Instance = new List<T>(); } public new static IList<T> Instance { get { return Singleton<IList<T>>.Instance; } } } public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>> { static SingletonDictionary() { Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>(); } public new static IDictionary<TKey, TValue> Instance { get { return Singleton<Dictionary<TKey, TValue>>.Instance; } } } public class Singleton { static Singleton() { allSingletons = new Dictionary<Type, object>(); } static readonly IDictionary<Type, object> allSingletons; public static IDictionary<Type, object> AllSingletons { get { return allSingletons; } } } }
Singleton类里面用一个Dictionary<Type, object>()集合来存储所有的单例对象。基于Singleton类创建一些泛型类Singleton,Singleton<IList>,SingletonList,Singleton<IDictionary<TKey, TValue>>和SingletonDictionary<TKey, TValue>。