【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函数简单分析了一下,还 ...
随机推荐
- 剑指Offer面试题:2.二维数组中的查找
一.题目:二维数组中的查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...
- ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程
好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: --> 开篇:上一篇 ...
- [史上最全]C#(VB.NET)中位运算符工作过程剖析(译)
原文地址CodeProject 目录 介绍 “二进制-十进制”相互转换 十进制->二进制 二进制->十进制 OR运算符(按位或|) OR运算符工作方式 FlagsAttribute AND ...
- ASP.NET MVC 5 Web编程2 -- URL映射(路由原理)
本章将讲述ASP.NET MVC5 的路由原理,即URL映射机制. 简单点就是解释:为什么MVC在浏览器输入地址就能访问到类(或类中的方法)?这是怎么做到的?我自己可以通过.NET写出一个自己的MVC ...
- 在C#代码中应用Log4Net(五)将Log4Net正确地封装在自己的类库中并进行调用
前面的几篇文章已经比较完整地解释了怎么使用Log4Net,但是我们可能需要将Log4Net的日志类封装在自己的类库中,以便C/S或B/S程序进行调用.下面的示例程序简单地分为两层,一个是应用程序层We ...
- Express4 启航指南
确实有感而发,Nodejs真的发展太快了,这么说的原因有两点:自己去年冬天买了本<了不起的Node.js>,里面介绍Express的版本还是2.x.x:前些天小伙伴买了本<Node. ...
- 使用python拼接多张图片.二三事
前几日在博客上看到一篇“使用python拼接多张图片”的Blog[具体是能将的图片名字必须是形如xx_1.png ... xx_100.png或者xx_001.png ... xx_100.png,拼 ...
- Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构
Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构 1. 索引的分类1 1.1. 按照存储结构划分btree,hash,bitmap,fulltext1 1.2. 索引的类型 按查找 ...
- 我所理解的Cocos2d-x
我所理解的Cocos2d-x(完全基于Cocos2d-x3.0,深度剖析计算机图形学,OpenGL ES及游戏引擎架构,全面提升游戏开发相关知识) 秦春林 著 ISBN 978-7-121-246 ...
- iOS—Xcode 7真机测试
Xcode 7真机测试详解 1.准备 注意:一定要让你的真机设备的系统版本和app的系统版本想对应,如果不对应就会出现一个很常见的问题:could not find developer disk im ...