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

标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分

首先说Mvc扩展框架,该Mvc扩展就是把以前的那个Mvc分区扩展框架迁移过来,并优化整合了一下

一、Mvc扩展框架主要功能:

1、Mvc的依赖注入(DI)功能(类MvcDependency)

  依赖IContainerFactory接口,不再依赖具体容器

2、Mvc全局过滤器(GlobalFilterProvider)

  配置在Mvc的依赖注入容器中就能自动被Mvc调用。其实逻辑很简单,就是继承IFilterProvider接口,对外暴露Filters属性,需要增加过滤器就配置到Filters属性中

3、分模块(Area分区)开发支持

  Area基类及相关支持类(AreaRoute、AreaListService)

4、分区过滤器(AreaGlobalFilterProvider)

5、分区注册的HttpModule(AreaMergeModule)

  使用该HttpModule初始化分区及分区的依赖注入容器配置

二、依赖注入(DI)也挺复杂的

1、Mvc的依赖注入(DI)支持

  Mvc使用IDependencyResolver接口定义依赖注入,实现该接口并覆盖Mvc默认的DI配置,主要是把Mvc的依赖注入适配到容器来支持,以便使用容器来做

2、容器的依赖注入(DI)

  成熟容器支持依赖注入功能,为用户构造对象,并按当前对象(类)的依赖注入配置递归进行依赖注入操作

3、框架的依赖注入(DI)扩展(Fang.DI)

其一、本框架不依赖任一成熟容器,所以为了便于更好的使用DI技术,所以扩展了DI支持,以便使用任意容器功能都可以使用DI

其二、每种成熟容器的DI配置(标注)的方式不一致,导致使用特定容器的DI写的代码给使用其他容器技术的团队复用性不好

其三、本框架支持“快速检索黑科技”(参考核心容器那篇),使用该依赖注入(DI)扩展可以使用“快速检索黑科技“语法定义依赖注入标记

本篇内容涉及”Mvc扩展框架“子模块,”依赖注入(DI)扩展“子模块、主框架的核心容器及外部成熟容器(本篇继续使用Unity容器做外部成熟容器示例)


介绍的差不多了,先上例子

一、Mvc的依赖注入(DI)

1、使用Unity容器做DI

1.1 配置初始化

首先注入Unity容器,初始化Mvc依赖配置(替代Mvc默认的DependencyResolver)

1.2 建一个测试页面,使用Unity配置一个依赖注入服务

Ok,依赖注入成功

1.3 看一下Unity容器配置

2、使用Fluent代码做依赖注入

木有问题,效果出来。使用容器技术不一定非要用配置文件,Fluent方式也是配置容器的选项之一。当然配置文件搭配Fluent也是木有问题。

以上例子虽然简单,但用到了很多技术,有Mvc扩展框架、Unity容器及依赖注入(DI)扩展。

二、全局过滤器

1、过滤器代码很简单

以上只是ActionFilter的例子,Mvc支持的AuthorizationFilter\ExceptionFilter\ActionFilter\ResultFilter都可以这样配置,是不是很爽啊

2、看一下容器配置信息

有人说,你能用Fluent代码再作一次过滤器的例子吗?当然可以,只要创建一个IFilterProvider对象,注入到容器里面就可以了。没必要再做这个重复的工作。

我是非常推荐使用配置文件的方式,项目和调用的服务具体实现类才能彻底的隔离,才能更好的体现IOC容器的作用

三、分模块(area分区)

1、分区路由配置

2、两个分区配置

3、执行效果

以上两个分区运行结果,且两个分区调用的服务稍有不同,导致结果稍不同

分区的讲解不展开了,参看原来的文章”分区扩展框架“,只是分区过滤器稍有不同,后面再讲解分区过滤器

四、分区过滤器

1、还是使用全局过滤的代码,直接看结果

以上其实是分区过滤器和全局过滤器整合测试,两个分区共用一个全局过滤器GlobalTest,每个分区还有自己的分区过滤,效果不错吧

2、看一下过滤器配置(配置和全局过滤器是不同的)

看以上配置,分区过滤器和全局过滤器配置几乎一致(实际上也是继承关系),而且从分区中拆分出来,效果和原来(参看原来文章”分区扩展框架“)一样,结构是不清晰多了,而且也减轻了area初始化的负担,算是优化吧。

3、AreaMergeModule(分区注册的HttpModule)配置

配置方法还是那么简单,这方面的内容还是参看前篇文章

五、框架的依赖注入(DI)扩展(Fang.DI)

1、配置方式

和Unity的属性依赖注入相似度很高吧,只是命名空间不一样,但是作用大很多,还可以对不支持DI的容器进行DI(依赖注入)

2、执行效果

效果和Unity容器配置的一样。使用DI扩展对不同容器就可以统一依赖注入语法了。但是美中不足的是,我只在依赖注入扩展模块(Fang.DI)中实现了属性依赖注入。

这种扩展DI并不会覆盖原容器(比如Unity)的DI,只是补充,也会检测DI的属性是否已经初始化(!=null),也就是说扩展的DI是补充,原容器DI成功就不再DI,也可以同时使用(如果你不嫌乱的话)

我个人认为有属性依赖注入就够用了。当然很多人都有反驳的理由,最为关键的应该是安全性。如果我们把服务的初始化都交给容器,不要去修改服务对象,也就没有安全一说;如果你非要修改,就算是private的,类内部也可以修改,外部使用反射也能修改,没有绝对的安全性。

3、使用“快速检索黑科技“语法定义依赖注入标记

上面标注中重点要看到有个点(.),本例就是把全局服务容器中的默认时间格式化服务DI到当前Controller的属性上;也就是说可以把任意容器中的任意服务都DI过来,绝对的黑科技!!!

六、各功能模块都是如何协同工作的

1、Mvc扩展框架、Unity容器及依赖注入(DI)扩展模块相互独立,相互没有依赖关系

上图可以清晰看到,他们相互独立,但是他们都依赖着面向接口主框架(Fang.Framework),那主框架就非常重要,各自和主框架的关系就非常重要

(这就是我设计这个框架的初衷,以后增加再多的功能,或者引入再多的第三方组件,都只依赖主框架,都是对作为主框架的服务(插件)或者Mvc等Ms框架的插件来调用运行)

2、以上例子中各模块式如何工作

先看项目配置

以上先注册Unity容器,再注册依赖注入扩展(Fang.DI),分区及其路由规则使用HttpModule注入

我们还看到一个有意思的东西,初始化DI居然和初始化Unity容器那么的相似,其实DI扩展就是容器封装,说白了就是容器扩展,也就是说我是通过扩展容器来实现DI的

3、那我们看看依赖注入扩展(Fang.DI)怎么工作的

3.1 依赖注入扩展(Fang.DI)项目截图

A:DependencyAttribute就是依赖注入标注(Attribute),靠他标注哪个属性需要注入

B:Container和ContainerFactory是容器封装,封装后的容器对象就有了扩展出来的DI功能,所以我们调用的原始容器即使没有依赖注入功能经过这么一封装就有依赖注入功能了

C:PropertyChecker类就是负责找到那些属性需要依赖注入,PropertyChecker实例对象封装了一个属性的依赖注入过程(功能)

D:CheckContainer定义了一个使用容器处理依赖注入的接口(ICheckContainer)及多个Checkers属性包含多个ICheckContainer对象,并自己实现ICheckContainer接口

(其实就是容器处理依赖注入的组合模式,其中前面的PropertyChecker就是实现的ICheckContainer接口,一般来说CheckContainer对象包含一个PropertyChecker的数组)

注:这块刚开发完,CheckContainer这个命名有点问题,以后再改,如果有建议好的命名可以回复我一下,谢谢

3.2 再来看一下CheckContainer的主要逻辑(还是比较简单的)

解读一下:

A:字典(ConcurrentDictionary)按类型缓存对象

B:MonitorWrapper是我写的一个对象锁的封装,避免死锁和控制锁定的最长时间(默认50毫秒)及返回是否锁定成功;

(既然是缓存,那锁只是帮我们提高缓存利用率的工具,所以不管是否锁定成功,都继续执行)

C:如果没有缓存,我们按类型获取可写并标注(DependencyAttribute)的属性,按属性构造注入功能(ICheckContainer)对象

D:这里的注入比较简单,我直接使用的反射了;

(打算以后使用Emit,但是我的Emit功底太差,Emit个功能要半天,以后在好好学习Emit技巧或者花时间好好调试,为了性能不能有半点马虎)

本篇内容就讲完了。本篇内容和原来的那篇”分区扩展框架“有很多相同的地方,但本质的东西区别很大。原来的分区框架是强依赖Unity容器的,本框架是使用配置到主框架的容器工厂。

很多配置也都有更多的自定义化,而且本框架也照顾到不使用分区的开发使用者的利益(全局过滤和MvcDependency(DI))。

还有就是依赖注入扩展模块(Fang.DI)和Mvc扩展框架无缝结合,真是如虎添翼。当然,Fang.DI在非Mvc中的也是一样有效,这里就不举例说明了。

 

面向接口可扩展框架之“Mvc扩展框架及DI”的更多相关文章

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

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

  2. 用实体框架搭建MVC程序框架(全部)

    第一步:1.新建项目 2.新建domain类库 3.新建Data类库 4.为上面的1.2.3添加实体框架nuget包.(可以右键管理nuget包来查找entityframework,当然也可以通过程序 ...

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

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

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

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

  5. Asp.net 面向接口可扩展框架之应用程序上下文作用域组件

    在团队中推广面向接口开发两年左右,成果总体来说我还是挺满意的,使用面向接口开发的模块使用Unity容器配置的功能非常稳定,便于共享迁移(另一个项目使用只需要复制配置和调用接口即可),如果再配合上DI那 ...

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

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

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

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

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

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

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

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

随机推荐

  1. c语言string.h和memory.h某些函数重复问题

    在C语言中,为了使用memset()函数,你是选择#include <string.h>还是<memory.h>?两个都可以,如何选择? <string.h>,标准 ...

  2. vtk基础编程(2)-读取数据文件中的坐标点

    原文地址: http://blog.csdn.net/chinamming/article/details/16860051 1. 案例说明 在实际计算中,常常需要大量的数据, 这个时候数据文件就必不 ...

  3. perl encode_utf8必须用在utf8环境

    [root@wx03 mojo]# cat test.pl use Mojolicious::Lite; use JSON qw/encode_json decode_json/; use Encod ...

  4. State Design Pattern 状态设计模式

    设置好内部状态,然后依据不同的函数作为行为模式,进行状态转换. 有点像Finite Automata算法,两者的思想是一样的. 会Finite Automata,那么这个设计模式就非常easy了. # ...

  5. response.sendRedirect("")和request.getRequestDispatcher("").forward(req,resp);

    1:request.getRequestDispatcher("转发路径").forward(req,resp)该语句是实现请求转发的,当请求进入到该servlet中执行到该语句时 ...

  6. SQL SERVER 2008- 字符串函数

    /* 1,ASCII返回字符表达式中最左侧字符的ASCII代码值 仅返回首字母的ASCII码值 parameter char或varchar returns integer */ SELECT ASC ...

  7. LINQ to SQL的一些简单用法

    static void Main(string[] args) { var personList = new List<Person> { new Person() { PersonID= ...

  8. new对象数组时的内存布局

    #include <iostream> #include <limits> using namespace std; #define SAFE_DELETE(x) \ { \ ...

  9. js 常用方法记事本

    1.获取被选中行的名称<tab选项卡中为iframe> /* S 获取首页被选中的选项卡名称 */ var currTab = $("#layout_center_tabs&qu ...

  10. 性能测试之LoardRunner工作原理

    概述: 1.VuGen 2.控制器 3.负载发生器 4.分析器 VuGen,它的作用是捕捉用户的业务流,并最终将其录制成一个脚本.在录制脚本前首先选择一种协议,接着在客户端模拟客户实际使用过程中的业务 ...