[转载]Xoohoo系列(一):概述

[转载]Xoohoo系列(一):概述 – alby – 博客园.

作为一个开发者,我们免不了要做很多重复的事情。我们不只在重复别人造轮子,也在重复自我浪费时间——我们应该有一种罪恶感。庆幸的是很多人在帮助我们尽可能的减少这种重复,他们提出或总结了很多的宝贵的思想,开发了很多的有用的开发辅助工具。比如设计模式、类库、O/RM,代码生成器,以及更具体的CMS(Content Management System)等等。设计模式让我们在设计思想得到一定程度的解放,在设计方向上给予指引。这就像乘法口诀表,不用我们算个简单的3721还需要掰手指 头;类库如.Net的BCL(Base Class Library)、FCL(Framework Class Library)等,以官方发布的形式将一些常用的功能进行了封装。当然,还有公司的类库或自己的私房类库;O/RM让我们在领域模型和关系数据库的映射 上提高开发效率。据统计如果不使用O/RM,在映射方面需要花去总体开发时间的30%-40%;代码生成器则是将有规律的集中的重复的工作交给程序来处 理;CMS在应用的层次上减少了重复工作,比如WordPress,DotNetNuke等。

Xoohoo又试图解决哪些方面的问题呢?

Xoohoo基于ASP.NET MVC(以下简称MVC)3的框架,其前身是微软的开源项目Oxite。遗憾的是后者停止了开发目前还停留在MVC 1。庆幸的微软提供了另一个开源项目Orchard供我们选择,二十四画生对Orchard颇有研究。不管是Oxite还是Orchard,他们从一开始就试图给用户提供一个可用的产品(Blog,但不仅限于此),并提供了超强的扩展性。

Xoohoo的目的不是要给您一个现成的产品,而是一个轻量开发框架,旨在能为您减少那么一点点重复的工作。如果您开发一个新的基于MVC的项目,希望您能试试。

您 首先可以将之看作是一个类库,对MVC 3进行了扩充。它借鉴并使用了一些优秀博文或开源项目的代码。由于资料比较零散,不再列出,在此一并表示感谢;其次将之作为一个小框架,在此基础您可以开 发自己的模块(插件),并能进行无缝整合。如果愿意,您还可以将某些模块拿出来分享。

一、Xoohoo是一个ASP.NET MVC 3的扩展类库

将Xoohoo作为一个类库,我相信您总等找到您所需要的。

1、ActionFilter

Xoohoo内置了若干的AtionFilter,包括TimerActionFilter、CompressActionFilter、ErrorExceptionFilter以及各种的AuthorizationFilter。

TimerActionFilter能计算Action的执行时间:

image

CompressActionFilter能对输出进行压缩(gzip,deflate)。
ErrorExceptionFilter类似于MVC内置的HandleErrorAttribute,配合Xoohoo内置的日志模块,可以进行日志记录;配合Xoohoo的皮肤模块,错误提示View还可以换肤。
各种的AuthorizationFilter提供了非常灵活的授权(权限)认证,以后会有专门的篇幅加以介绍。

2、ActionInvoker

XoohooControllerActionInvoker重写了MVC内置的ControllerActionInvokerCreateActionResult等方法,使其支持AJAX请求,以及更灵活的Action返回值类型。

比如有Action:

   1: public ActionResult List()
   2: {
   3:         return View(new List<Article>());
   4: }

如果是AJAX请求,您需要在重新实现一个Action,或者在Action内部进行一次判断:

   1: public ActionResult List()
   2: {
   3:     if(Request.IsAjaxRequest())
   4:         return Json(new List<Article>());
   5:     else
   6:         return View(new List<Article>());
   7:
   8: }

如果使用XoohooControllerActionInvoker,只需要这样写:

   1: public List<Article> List()
   2: {
   3:     return new List<Article>();
   4: }

MVC内置的ControllerActionInvoker,如果Action返回的不是一个ActionResult类型的值,将会调用Convert.ToString方法生成其字符串形式,再使用字符串生成一个ContentResult
XoohooControllerActionInvoker也会根据Action返回值的类型进行判断。
如果是简单类型,如int,string等,则采用ControllerActionInvoker相同的方式,即调用Convert.ToString方法生成其字符串形式,再使用字符串生成一个ContentResult。
如果是复杂类型,则进行进一步判断是否是AJAX请求。如果是,将生成一个JsonResult并将Action返回值赋给 JsonResult的Data属性;否则将返回值赋给Controller的ViewData的Model属性,然后生成一个ViewResult。
怎么样,是不是很灵活很简洁?

3、ActionResult

Xoohoo扩充了一些ActionResult,如RssResult、XmlResult等,比较简单不再累述。

4、ControllerFactory

ControllerFactory是用于查找Controller类型并创建Controller实例的。一般我们不需要改变查找 Controller类型的方式。在MVC3中,至少有两种途径可以改变创建Controller实例方式,一是自定义 ControllerFactory;二是重新实现一个IControllerActivator,在实例化DefaultControllerFactory时作为构造函数参数传递进去。

Xoohoo选择了前者,实现了一个DependencyInjectorControllerFactory类。因为在创建Controller 实例后,还需要重新设置Controller的ActionInvoker。其实这正是 DependencyInjectorControllerFactory类存在的意义。

备注:在MVC2中,仅仅想要在创建Controller获取IoC/DI容器的支持,就需要自定义ControllerFactory。这在MVC3已经不是必需的,只需要创建一个容器类实现IDependencyResolver接口,然后在Global.asax中调用DependencyResolver.SetResolver方法即可。

5、ModelBinders

DefaultModelBinder是 非常强大的,或者是一个重量级的。如果想要稍微提供模型绑定的效率,或想要绑定更可控,就用自定义ModelBinder。Xoohoo增加了几个 ModelBinder,包括GuidListModelBinder、Int32ListModelBinder、 PagingInfoModelBinder、IPAddressModelBinder等。通过名称就可以看出它们的作用。

6、ValidationAttribute

MVC3的数据校验机制非常好用,只需一处设置,可以为您生成客户端校验脚本(如果开启Unobtrusive,则会生成html attributes),并支持服务器端验证。

Xoohoo扩展了几个常用的正则验证,如Email,Url,IP等;并提供一个比较验证CompareAttribute,可以进行日期、数字等类型的>、<、>=、<=、!=等比较,而MVC3内置的比较验证只能比较是否相等。
image

image

7、RouteConstraint

Xoohoo同样提供一些常用的路由规则,如IsInt、IsLong、IsGuid等,他们实现自IRouteConstraint接口。(随便提一下,与路由相关的,在老赵提供的子域名解决方案基础上进行了扩展完善)

8、FilterProvider

MVC提供了一种AOP(面 向侧面的程序设计)的编程模式,我们可以为Controller或Action设置各种Filter,包括ActionFilter、 ResultFilter、ExceptionFilter、AuthorizationFilter,在一定的阶段将执行这些Filter。关于 Filter的执行流程,可以看看xfrog这篇图文并茂的博文

MVC3提供了三种FilterProvider,它们提供了设置或获取Filter的方式,相较于MVC2,这又是一个扩展点。包括:GlobalFilterCollectionFilterAttributeFilterProviderControllerInstanceFilterProvider
GlobalFilterCollection可以通过GlobalFilters.Filters静态属性访问,用户增添全局的,作用于所有Controller的所有Action的Filter;
FilterAttributeFilterProvider用于获取基于Attribute的Filter;
ControllerInstanceFilterProvider用于获取Controller实例Filter(Controller实现了IActionFilter等接口,其本身就是一个Filter)。

Xoohoo提供了一种基于外部配置的Filter获取方式:FilterRegistryFilterProvider。可以设置某些 Controller具有某些Filter,也可以设置某些(不是全部)Action具有某些Filter。还可以某些Route或具体有某些 RouteValue,DataToken(如Area)的路由具有某些Filter(如果您愿意,还可以根据cookie值来配置)。它还有个优点就是 能将Filter像Golbal Filters一样缓存起来,不用像Attribute形式的Filter那样使用时还得通过反射从元数据中获取并进行反序列化。
可以通过FilterRegistry.Filters静态属性添加Filter,这和GlobalFilters.Filters也类似。

9、Extensions

Extensions就是一些扩展方法集。
Xoohoo为了支持更多的需求,几乎扩展了MVC3内置的相关的所有HtmlHelper、UrlHelper相关的扩展方法,用于支持如 二(多)级域名、更丰富的HtmlHelper、UrlHelper等。当然还有一些零散而好用的扩展就不一一列出。更丰富的扩展方法可以看看鹤冲天的相关博文。

二、Xoohoo是一个框架

Xoohoo作为一个框架,它支持插拔式的模块(插件)开发方式;内置有RBAC(Role-Based Access Control)模块,日志模块,缓存模块,并皆可替换;支持IoC/DI

开发一个新的模块非常简单,只需要实现一个接口,并在配置文件中增加模块的配置即可。

1、什么叫Xoohoo的模块(Module)

我们约定,实现了IModule接口的类称为模块。接口定义:

   1: public interface IModule
   2: {
   3:     /// <summary>
   4:     /// 模块名称
   5:     /// </summary>
   6:     string ModuleName { get; }
   7:     /// <summary>
   8:     /// 模块设置
   9:     /// </summary>
  10:     AppSettingsHelper Settings { get; set; }
  11:     /// <summary>
  12:     /// 初始化模块
  13:     /// </summary>
  14:     void Initialize();
  15:     /// <summary>
  16:     /// 注册路由配置
  17:     /// </summary>
  18:     void RegisterRoutes();
  19:     /// <summary>
  20:     /// 注册过滤器
  21:     /// </summary>
  22:     /// <param name="filterRegistry"></param>
  23:     /// <param name="globalFilters"></param>
  24:     void RegisterFilters(FilterRegistryFilterProvider filterRegistry, GlobalFilterCollection globalFilters);
  25:     /// <summary>
  26:     /// 注册模型绑定器
  27:     /// </summary>
  28:     /// <param name="modelBinders"></param>
  29:     void RegisterModelBinders(ModelBinderDictionary modelBinders);
  30:     /// <summary>
  31:     /// 卸载模块
  32:     /// </summary>
  33:     void Unload();
  34: }

模块包括模块名称(ModuleName)、模块设置(Settings)、初始化方法(Initialize)、注册路由方法 (RegisterRoutes)、注册过滤器方法(RegisterFilters)、注册模型绑定器方法 (RegisterModelBinders)、卸载模块方法(Unload)。Xoohoo提供了一个实现了IModule接口的抽象类Module, 一般情况下,我们建议你在设计新的模块时,实现抽象类Module而不是IModule接口,这样会让您开放起来更简单。

2、模块的配置

模块开发完成后,只需要将模块配置入Xoohoo.config即可生效。修改Xoohoo.config会导致AppDomain回收,所以不用去手工重动站点。当然,如果涉及数据库建表之类的操作,暂时还得您自己手工处理。
image

3、模块的加载

网站接收到第一次请求时,将会读取模块配置文件Xoohoo.config(位于站点的Configs目录,可自行更改)。获取模块的类型,创建模块的实例,依次调用模块的几个注册方法,将路由配置、Filter过滤器、模型绑定器配置加入MVC中。
更详细的关于模块定义及加载的内容,以及Xoohoo内置的几个模块的介绍,将放在之后的博文中。

4、后台服务的加载
后台服务是一个实现了IBackgroundService接口的类,它有对应的后台服务执行器(BackgroundServiceExecutor)负责服务的调度执行。

如果要定时完成一些任务,如邮件报告服务器资源信息,则可以定义一些后台服务。它的加载方式类似于模块的加载,并在模块加载完毕之后加载。
更详细的关于后台服务定义及加载的内容,将放在之后的博文中。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏