在团队中推广面向接口开发两年左右,成果总体来说我还是挺满意的,使用面向接口开发的模块使用Unity容器配置的功能非常稳定,便于共享迁移(另一个项目使用只需要复制配置和调用接口即可),如果再配合上DI那就是爽到底,也很好扩展(操作的数据库、表、资源等都可以配置)。

但是由于当时开发的匆忙(边开发边应用),留下一些比较致命的问题:

1、很多接口定义的不合理,通用性和扩展性不好

2、固定死了使用Unity容器,如果更大面积推广有问题,有些人已经很熟悉其他容器了,再来重新学Unity没有必要

3、配置比较麻烦,需要简化

所以我觉得有必要重新开发一个框架,对原框架取其精华去其糟粕,再吸收开源项目(含微软开放源代码的部分),争取做出一个像样一点的东西并开源出去...

这里插一句,前面有写一个Asp.net Mvc分区扩展框架系列没有写完的原因,其一是赶时间做这个框架,其二是重新做新框架,所有剩下的文章按新的框架来写会更好


这里要讲的是本框架中一个小的组件,应用程序上下文组件(AppContext),本组件有参考博客园大神的文章,这里先不注明出处(如果文章的作者介意,我再修改博文标注)

下面开始介绍本组件的主要使用场景

1、不同对象和方法间传递数据的新方式,看例子

看运行结果:

有人会说,你就作吧,修改一下A方法返回那个随机数,修改B方法增加一个参数接受这个随机数,So Easy。

但是在现有完成架构上增加一个附属功能,就把签名改了是很恐怖的事情。实际项目中产生对象方法和其他需要调用对象的方法可能没有调用链,或者调用链非常复杂,你要把涉及的所有方法都改一边,那系统估计差不多要被你改"废"了

在现实项目中并不推荐大规模的这样使用,只有在扩展附属功能,Aop或者在现项目扩展需要,慎重之下一个解决方案而已,性能肯定是比直接传要差不少,权当是应用程序上线文缓存来使用。

以上代码按照预期的效果运行了,看似简单功能,后面原理还是挺复杂的

2、线程安全调用

以上用两个线程对上下文中读取和写入数据,看数据是否会串(线程是否安全),看执行结果:

稍微解读一下:

A:线程6先运行,从上下文中读取键为test类型string的值为空,阻塞1000毫秒,再写入键为test,类型为string的值1000,再阻塞1000毫秒

B:线程11从上下文中读取键为test类型string的值为空,阻塞14毫秒,再写入键为test,类型为string的值14,后阻塞14毫秒

C:线程11从上下文中读取键为test类型string的值为14

D:线程6从上下文中读取键为test的string的值为1000

E:两个线程交替运行,各自读取和写入的值互不影响

所以建议定义全局静态变量的就省省吧,那样线程不安全,危险很大

3、有人会提到HttpContext

确实HttpContext.Current.Items可以实现这样的效果,但是HttpContext.Current并不是无处不在,非Web应用程序为null

就算是Web项目也不能滥用HttpContext.Current,在异步线程里面该属性也是null,不信的可以试试

但是HttpContext.Current还是很有用的,我这里实现的AppContext就有调用HttpContext.Current,如果为null,再调用另一个更神秘的东西CallContext

大家看一下实现代码:

在web程序中有异步操作会有线程切换,需要线程间复制上线文对象,使用HttpModule(以下代码来自一个博客园大神,我几乎没改)

4、服务(配置)作用域

4.1 先看建模代码

稍微解读一下:

A:Greet是用来打招呼,name对who发一个问候语

B:Person明显就是代表一个人,其中有一个Chindren属性,代表从属子对象(为了简化使用相同类型)

C:Person有一个Sayer属性,用来对其他"人"打招呼的

D:从方法Greet(Greet sayer, Person person)可以看出,如果取不到sayer对象会打招呼失败(提示sayer is miss)

E:对另一个对象Great的时候会遍历每个子对象分别对那个对象"问候"一下(这家的小孩还真有礼貌,大人问候谁,每个小孩都问候他)

4.2 再看测试代码

也解读一下:

A:定义了a,a1,b及a的另一个子对象

B: 其中只有a对象设置了Sayer属性

C:a对象Great了b(其中隐含a的所有子对象都对b进行Greate),之后a1对象单独Greate了一下b

4.3 看运行结果

哈哈,看到结果是不是有点惊讶啊

A:a对b的Hello是成功的很正常,但是a的两个子对象也对b的Hello成功了

B:更神奇的是,a1单独对b的Hello缺是失败的(不是继承了父对象的属性)

C:这里对上线文又进了一步,是作用域,只有a对b使用自己的Sayer属性时,其他对象(不一定是自己的子对象)也可以截获Sayer的值,但是等a对象使用完毕后就回收了,其他人就用不了了

4.4 原理解析

这里有一个using的作用域,AppContext.CreateResource在上线文中注册或者查找类型为Greate名字为A的,候选值为Sayer的对象,保存在resource.Entity中

4.5 来看一下实现的源代码

哈哈,是不是有点复杂啊

A:实现IDisposable以便使用using来控制作用域

B:Dispose也不是简单的就把作用域的对象删除,如果_needDispose为false不删除对象(不是自己创建的对象无权删除)

C:除了删除有的时候还要Restored(_needRestored为true),自己的作用域结束,把备份的_entity0还回去

D:Init方法尝试从作用域获取对象并备份到_entity0,如果本次候选对象无效直接使用作用域已有对象,如果有效就覆盖作用域(有_entity0备份能还原回来)

E:是不是非常有意思,就像定义变量一样,小作用域可以覆盖上级作用的变量,离开小作用域,外面作用域的变量又可以使用了

5、作用域的作用

  5.1 我特意开发这个功能是用来简化系统配置的

5.2 比如日志(含异常调试日志)几乎是每个对象都需要的功能

    如果每个对象都配置这些通用属性,配置的工作量太大了,配置文件太乱了

如果硬编码写死,那岂不就倒退到八百年前了

并不是所有都不配,只把特殊需要的配置,如果需要日志在最外面配置(或者只初始化一个作用域),里面调用的子对象也都可以共享外层的配置(共享日志服务)

有人可能说冲突了怎么办,可以用name隔离

6、应用程序上下文缓存

这个缓存的作用域只能是当前会话(线程或者Request),所以天生的线程安全(所以那个字典我都没用ConcurrentDictionary)

有人可能要笑话我,缓存不都是分布式吗?你那个缓存利用率太低了吧?

是的,你要说缓存利用率,确实不能和分布式比。但是要想到这个比session还session(不用清除下次请求重新初始化,也不用担心被人杜撰(修改sessionId))的高速缓存(直接字典)

自然也和session一样不用担心用户数据会串、存放用户登录状态、权限等都不是问题

用起来简单的不得了,直接New就可以使用,哪怕定义一个全局静态变量都是“线程(会话)安全”的,也可以配置在容器里面放心使用

测试项目下载

该组件暂时就先写这么多吧。写这篇文章的目的除了给大家分享自己的东西外,最主要的还是想得到博客园大神的指导,因为框架一旦开始使用再做调整就很要命,其一希望框架能做的更通用更好用,大家一起使用。其二把可能的问题尽早的发现,在正式使用之前更加完善。有些硬伤,比如接口、方法签名定义等如果不合理推广后就不好修改了,可能只能作为框架的缺陷存在了。接口一改,依赖这个接口的所有实现类都要改,很恐怖的。也是因为原来开发匆忙的框架“缺陷”太多,我不得不下定决心开发新框架。

这么多天每天长时间写代码,每天加班加点都写得全身冒汗,也写出了不少代码,却是今天下班后第一次调试,并且调试通过了一个我非常喜欢的上线文作用域组件(当然还有优化的地方)

下面简单介绍一下这个框架:

以下是项目解决方案截图:

A:第一张图是解决方案,部分扩展功能项目,这些需要很多人参与进来完善

B:后面的四张图是框架主项目的截图,大部分都是已经开发完成但还未测试的功能,其后是大量测试改bug和完善功能

主框架及相关项目我会在这里系列里面逐个测试优化后在发布出来,希望大家一起帮忙看一下,提供意见和建议

C:主框架本身并不力求解决所有方法,而是定义一些通用功能、逻辑的接口,对部分接口提供默认实现及部分“设计模式”功能,其他功能在其他项目中再扩展实现

D:主框架不含对具体哪种数据库或者哪种ORM工具的调用和不含具体开源外部日志组件和容器等调用(这些应该在外部扩展项目中对接)

E:该框架并不是要推翻系统的东西,而是整合,增加扩展性,给程序员带来更多便利和选择

F:总之主框架主要是抽象主要接口、实现部分非常通用的功能,尽量少引用外部

G:其他功能尽量继承按主框架的接口来开发,以便方便集成到主框架,或者其他模块间相互调用却不相互引用

Asp.net 面向接口可扩展框架之应用程序上下文作用域组件的更多相关文章

  1. Asp.net 面向接口可扩展框架之使用“类型转化基础服务”测试四种Mapper(AutoMapper、EmitMapper、NLiteMapper及TinyMapper)

    Asp.net 面向接口可扩展框架的“类型转化基础服务”是我认为除了“核心容器”之外最为重要的组成部分 但是前面博文一出,争议很多,为此我再写一篇类型转化基础服务和各种Mapper结合的例子,顺便对各 ...

  2. Asp.net 面向接口可扩展框架之核心容器(含测试代码下载)

    新框架的容器部分终于调通了!容器实在太重要了,所以有用了一个名词叫“核心容器”. 容器为什么那么重要呢?这个有必要好好说道说道. 1.首先我们从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘 ...

  3. Asp.net 面向接口可扩展框架之业务规则引擎扩展组件

    随着面向接口可扩展框架的继续开发,有些功能开发出现了"瓶颈",有太多的东西要写死才好做.但写死的代码扩展性是非常的不好,迷茫中寻找出入... 进而想到我以前开发的好几个项目,都已有 ...

  4. Asp.net 面向接口可扩展框架之消息队列组件

    消息队列对大多数人应该比较陌生.但是要提到MQ听说过的人会多很多.MQ就是英文单词"Message queue"的缩写,翻译成中文就是消息队列(我英语差,翻译错了请告知). PS: ...

  5. Asp.net 面向接口可扩展框架之“Mvc扩展框架及DI”

    标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把以前的那个Mvc分区扩展框架迁移过来,并优化整 ...

  6. Asp.net 面向接口可扩展框架之数据处理模块及EntityFramework扩展和Dapper扩展(含干货)

    接口数据处理模块是什么意思呢?实际上很简单,就是使用面向接口的思想和方式来做数据处理. 还提到EntityFramework和Dapper,EntityFramework和Dapper是.net环境下 ...

  7. Asp.net 面向接口可扩展框架之类型转化基础服务

    新框架正在逐步完善,可喜可贺的是基础服务部分初具模样了,给大家分享一下 由于基础服务涉及面太广,也没开发完,这篇只介绍其中的类型转化部分,命名为类型转化基础服务,其实就是基础服务模块的类型转化子模块 ...

  8. 面向接口可扩展框架之“Mvc扩展框架及DI”

    面向接口可扩展框架之“Mvc扩展框架及DI” 标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把 ...

  9. net 面向接口框架

    Asp.net 面向接口框架之应用程序上下文作用域组件 在团队中推广面向接口开发两年左右,成果总体来说我还是挺满意的,使用面向接口开发的模块使用Unity容器配置的功能非常稳定,便于共享迁移(另一个项 ...

随机推荐

  1. Ubuntu 16 安装ElasticSearch

    首先安装Java,参见博客:http://www.cnblogs.com/1zhk/p/6056406.html 下载ElasticSearch安装包 curl -L -O https://artif ...

  2. slave IO流程之二:注册slave请求和dump请求

    slave IO流程已经在http://www.cnblogs.com/onlyac/p/5815566.html中有介绍 这次我们要探索注册slave请求和dump请求的报文格式和主要流程. 一.注 ...

  3. linux创建进程fork的方法步骤

    fork创建进程 函数原型如下 #include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数 pid_t fork(void); //void代表没有 ...

  4. 创建 flat network - 每天5分钟玩转 OpenStack(87)

    上一节我们讨论了 flat network 的原理,今天就来创建 "flat_net" 并分析底层网络的实现. 打开菜单 Admin -> Networks,点击 “Crea ...

  5. Html,Css,Dom,javascript细节总结

    最近愈发觉得基础的重要性,细节决定成败,所以希望能够将自己注意到的搜集到的一些关于前端的小细节小知识整理出来,更好的方便自己记忆回顾. 1.在构建网页Html框架时,尽量只给外层标记(即是父标记)定义 ...

  6. Don't let self-built concept imprison yourself

    If Self-inferiority is disease, but self-confidence is hazard. Leo moon personalities can be extreme ...

  7. iOS开发之SQLite-C语言接口规范(二) —— Prepared Your SQL Statements

    在<SQLite的C语言接口规范(一)>中介绍了如何去连接打开数据库,本篇博客就介绍如何操作数据库,本篇主要给出了如何执行数据库查询语句(Select), 然后遍历结果集.本篇博客就直接使 ...

  8. geotrellis使用(十三)数据导入BUG解决方案说明

    Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 BUG说明 解决方案 总结 一.前言         ...

  9. iOS开发使用半透明模糊效果方法整理

    虽然iOS很早就支持使用模糊效果对图片等进行处理,但尤其在iOS7以后,半透明模糊效果得到大范围广泛使用.包括今年最新发布的iOS8也沿袭了这一设计,甚至在OS X 10.10版Yosemite中也开 ...

  10. CSS3中惊艳的gradient

    以前曾经记录过linear-gradient(线性渐变)和 radial-gradient(径向渐变)的语法. 可以参考<CSS3中border-radius.box-shadow与gradie ...