【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>。
【NopCommerce源码架构学习-二】单例模式实现代码分析的更多相关文章
- 【NopCommerce源码架构学习-一】--初识高性能的开源商城系统cms
很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...
- NopCommerce源码架构
我们承接以下nop相关的业务,欢迎联系我们. 我们承接NopCommerce定制个性化开发: Nopcommerce二次开发 Nopcommerce主题开发 基于Nopcommerce的二次开发的电子 ...
- NopCommerce源码架构详解--初识高性能的开源商城系统cms
很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...
- NopCommerce源码架构详解
NopCommerce源码架构详解--初识高性能的开源商城系统cms 很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...
- Nop--NopCommerce源码架构详解专题目录
最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...
- vnpy源码阅读学习(1):准备工作
vnpy源码阅读学习 目标 通过阅读vnpy,学习量化交易系统的一些设计思路和理念. 通过阅读vnpy学习python项目开发的一些技巧和范式 通过vnpy的设计,可以用python复现一个小型简单的 ...
- 如何快速为团队打造自己的组件库(上)—— Element 源码架构
文章已收录到 github,欢迎 Watch 和 Star. 简介 详细讲解了 ElementUI 的源码架构,为下一步基于 ElementUI 打造团队自己的组件库打好坚实的基础. 如何快速为团队打 ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- 【原】SDWebImage源码阅读(二)
[原]SDWebImage源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 解决上一篇遗留的坑 上一篇中对sd_setImageWithURL函数简单分析了一下,还 ...
随机推荐
- 给Macbook Pro更换固态硬盘并转移系统的最简单办法
没有固态硬盘,再快的CPU,再强悍的显卡,都是白搭,由于“木桶原理”,瓶颈就在这里啊.如今的固态硬盘价格跌了很多,我记得去年我买的120G的固态硬盘还要将近600元,而现在只需要不到400了. 我 ...
- MySQL COLUMNS分区
200 ? "200px" : this.width)!important;} --> 介绍 COLUMN分区是5.5开始引入的分区功能,只有RANGE COLUMN和LIS ...
- [译]如何防止elasticsearch的脑裂问题
本文翻译自blog.trifork.com的博文 地址是http://blog.trifork.com/2013/10/24/how-to-avoid-the-split-brain-problem- ...
- angularjs自动化测试系列之karma
angularjs自动化测试系列之karma karma test with jasmine 更好的利用工具是为了让生活更美好. 需要安装的东西: npm install karma -g mkdir ...
- Task C# 多线程和异步模型 TPL模型
Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task TaskCompletionSource 更通用, ...
- [汇编与C语言关系]3. 变量的存储布局
以下面C程序为例: #include <stdio.h> ; ; ; int c; int main(void) { ; char b[] = "Hello World" ...
- Python标准模块--functools
1 模块简介 functools,用于高阶函数:指那些作用于函数或者返回其它函数的函数,通常只要是可以被当做函数调用的对象就是这个模块的目标. 在Python 2.7 中具备如下方法, cmp_to_ ...
- JavaScript 命名空间
<script type="text/javascript"> Namespace=new Object(); Namespace.register=function( ...
- .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)
在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...
- 《ASP.NET Web API 2框架揭秘》样章(PDF版本)
<ASP.NET Web API 2框架揭秘>(详情请见<新作<ASP.NET Web API 2框架揭秘>正式出版>)以实例演示的方式介绍了很多与ASP.NET ...