zoukankan      html  css  js  c++  java
  • 【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>。

  • 相关阅读:
    Javascript中String()和new String()的区别——JS的包装对象
    文言色彩的客套话之感想
    面试时候可以问的问题集锦
    ES6的原始类型数据——Symbol
    python
    python
    python
    python
    python
    python
  • 原文地址:https://www.cnblogs.com/ezplusy/p/6038955.html
Copyright © 2011-2022 走看看