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

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

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

下面就是EngineContext的源码:

一、EngineContext

 using System.Configuration;

 using System.Runtime.CompilerServices;

 using Nop.Core.Configuration;

 namespace Nop.Core.Infrastructure

 {

     /// <summary>

     ///Provides access to the singleton instance of the Nop engine.

     ///提供了访问单例实例Nop引擎

     /// </summary>

     public class EngineContext

     {

         #region Methods

         /// <summary>

         /// Initializes a static instance of the Nop factory.

         /// 初始化静态Nop工厂的实例

         /// </summary>

         /// <param name="forceRecreate">创建一个新工厂实例,尽管工厂已经被初始化</param>

         [MethodImpl(MethodImplOptions.Synchronized)]

         public static IEngine Initialize(bool forceRecreate)

         {

             if (Singleton<IEngine>.Instance == null || forceRecreate)

             {

                 Singleton<IEngine>.Instance = new NopEngine();

                 var config = ConfigurationManager.GetSection("NopConfig") as NopConfig;

                 Singleton<IEngine>.Instance.Initialize(config);

             }

             return Singleton<IEngine>.Instance;

         }

         /// <summary>

         /// Sets the static engine instance to the supplied engine. Use this method to supply your own engine implementation.

         /// 设置静态引擎实例提供的引擎,

         /// </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

         #region Properties

         /// <summary>

         /// Gets the singleton Nop engine used to access Nop services.

         /// </summary>

         public static IEngine Current

         {

             get

             {

                 if (Singleton<IEngine>.Instance == null)

                 {

                     Initialize(false);

                 }

                 return Singleton<IEngine>.Instance;

             }

         }

         #endregion

     }

 }

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

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

二、Singleton

 using System;

 using System.Collections.Generic;

 namespace Nop.Core.Infrastructure

 {

     /// <summary>

     /// A statically compiled "singleton" used to store objects throughout the

     /// lifetime of the app domain. Not so much singleton in the pattern's

     /// sense of the word as a standardized way to store single instances.

     /// </summary>

     /// <typeparam name="T">The type of object to store.</typeparam>

     /// <remarks>Access to the instance is not synchrnoized.</remarks>

     public class Singleton<T> : Singleton

     {

         static T instance;

         /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this object for each type of T.</summary>

         public static T Instance

         {

             get { return instance; }

             set

             {

                 instance = value;

                 AllSingletons[typeof(T)] = value;

             }

         }

     }

     /// <summary>

     /// Provides a singleton list for a certain type.

     /// </summary>

     /// <typeparam name="T">The type of list to store.</typeparam>

     public class SingletonList<T> : Singleton<IList<T>>

     {

         static SingletonList()

         {

             Singleton<IList<T>>.Instance = new List<T>();

         }

         /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this list for each type of T.</summary>

         public new static IList<T> Instance

         {

             get { return Singleton<IList<T>>.Instance; }

         }

     }

     /// <summary>

     /// Provides a singleton dictionary for a certain key and vlaue type.

     /// </summary>

     /// <typeparam name="TKey">The type of key.</typeparam>

     /// <typeparam name="TValue">The type of value.</typeparam>

     public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>>

     {

         static SingletonDictionary()

         {

             Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>();

         }

         /// <summary>The singleton instance for the specified type T. Only one instance (at the time) of this dictionary for each type of T.</summary>

         public new static IDictionary<TKey, TValue> Instance

         {

             get { return Singleton<Dictionary<TKey, TValue>>.Instance; }

         }

     }

     /// <summary>

     /// Provides access to all "singletons" stored by <see cref="Singleton{T}"/>.

     /// </summary>

     public class Singleton

     {

         static Singleton()

         {

             allSingletons = new Dictionary<Type, object>();

         }

         static readonly IDictionary<Type, object> allSingletons;

         /// <summary>Dictionary of type to singleton instances.</summary>

         public static IDictionary<Type, object> AllSingletons

         {

             get { return allSingletons; }

         }

     }

 }

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

上一篇:将Spring源码转换为工程 + 导入Eclipse时缺失jar包


下一篇:js Date 关于时间获取问题