Asp.net MVC示例项目“Suteki.Shop”分析之Filter

在Suteki.Shop中对于Filter的使用上提供了两种方式,一种是从FilterAttribute(抽象类属性)以及 接口 IActionFilter和 IResultFilter中继承并实现。另一种是我们经常提到的从 ActionFilterAttribute 上继承方式来实现自己的ActionFilter。首先看一下第一种,同时它也是该项 目中被Action广泛使用的方式, 下面是类图:


当然图中最核心的 当属FilterUsingAttribute,它同时继承了 FilterAttribute类和 IAuthorizationFilter, IActionFilter, IResultFilter这三个接口,所以其所实现的功能与MVC中所定义的 ActionFilterAttribute如出一辙。同时,下面是其核心代码:

public class FilterUsingAttribute : FilterAttribute, IAuthorizationFilter, IActionFilter, IResultFilter
{
private readonly Type filterType;
private object instantiatedFilter;

public FilterUsingAttribute(Type filterType)
{
if (!IsFilterType(filterType))
{
throw new InvalidOperationException("Type '{0}' is not valid within the FilterUsing
attribute as it is not a filter type.".With(filterType.Name));
}
this.filterType = filterType;
}

private bool IsFilterType(Type type)
{
return typeof (IAuthorizationFilter).IsAssignableFrom(type)
|| typeof (IActionFilter).IsAssignableFrom(type)
|| typeof(IResultFilter).IsAssignableFrom (type);
}

public Type FilterType
{
get { return filterType; }
}

private T GetFilter<T>() where T : class
{
if (instantiatedFilter == null)
{
instantiatedFilter = ServiceLocator.Current.GetInstance(filterType);
}
return instantiatedFilter as T;
}

private void ExecuteFilterWhenItIs<TFilter> (Action<TFilter> action) where TFilter :class
{
var filter = GetFilter<TFilter>();

if(filter != null)
{
action(filter);
}
}

public void OnAuthorization(AuthorizationContext filterContext)
{
ExecuteFilterWhenItIs<IAuthorizationFilter>(f => f.OnAuthorization (filterContext));
}

public void OnActionExecuting(ActionExecutingContext filterContext)
{
ExecuteFilterWhenItIs<IActionFilter>(f => f.OnActionExecuting(filterContext));
}

public void OnActionExecuted (ActionExecutedContext filterContext)
{
ExecuteFilterWhenItIs<IActionFilter>(f => f.OnActionExecuted(filterContext));
}

public void OnResultExecuting(ResultExecutingContext filterContext)
{
ExecuteFilterWhenItIs<IResultFilter>(f => f.OnResultExecuting (filterContext));
}

public void OnResultExecuted(ResultExecutedContext filterContext)
{
ExecuteFilterWhenItIs<IResultFilter>(f => f.OnResultExecuted(filterContext));
}
}

在上面的OnAction..和 OnResult..事件中,都调用了ExecuteFilterWhenItIs这个泛型方法,而该方法的作用是对泛型约束中使 用到的相应IActionFilter进行操作,而获取相应的Filter实例的工作就交给了GetFilter<T>()方 法,因为该方法使用IOC方式将filterType以服务组件的方式进行创建,所以我们会看到在 ContainerBuilder(Suteki.Shop\ContainerBuilder.cs)中有如下代码,注意最后一行:

container.Register(
Component.For<IUnitOfWorkManager> ().ImplementedBy<LinqToSqlUnitOfWorkManager>().LifeStyle.Transient,
Component.For<IFormsAuthentication> ().ImplementedBy<FormsAuthenticationWrapper>(),
Component.For<IServiceLocator>().Instance(new WindsorServiceLocator (container)),

看来其最终会使用Castle框架所提供的IOC功能。

时间: 2024-12-01 14:53:33

Asp.net MVC示例项目“Suteki.Shop”分析之Filter的相关文章

Asp.net MVC示例项目“Suteki.Shop”分析之结束篇

到今天,这个系列的文章就要先告一段落了.其中我用了10篇文章也没有穷尽该项目的设计思想,只 能从中捡了一些我感兴趣的东西进行了分析和说明,正所谓兴趣是最大的动力.当然限于本人水平有限 ,难免有一些认识上的错误,也希望大家在回复中与我进行交流. 下面把一些还未穷尽的内容做一下罗列,以备感兴趣的朋友继续品味. 1.项目中使用了"Rhino.Mocks",有对单元测试和这个项目感兴趣的朋友可以通过测试 代码研究一下. 2.在下面三个文件夹下有大量的辅助类和扩展方法,其中有些代码大家可以很容易

Asp.net MVC示例项目“Suteki.Shop”分析之安装篇

作为这个系列的开篇,本系统会将我在研究这个项目源码中的一些思考和心得介绍给大家. 当然本系统决不是那种所谓的"最佳示范",里面所提到的使用技巧或设计思路只是给大家 在实际工作中提供一个参考,所谓"最好"之类的词汇都是"矬子里拔将军", 相信大家在成功的分析了几个MVC示例之后,会找到适合自己所在团队或公司使用的方式或思路的. 其 实在找一个合适的MVC示例上我已花费了"一些"时间,而这个例子对于我来说,还是相对不 错的(除了文

Asp.net MVC示例项目“Suteki.Shop”分析之IOC(控制反转)

在Suteki.Shop中,未使用微软自已的Unity框架来实现IOC,而是使用了大名鼎鼎Castle Windsor. 因为引用了Windsor,就有必要简要介绍一下.而我的理解,这个IOC容器(Container)包括下 面几个重要概念: 容器(Container):Windsor是一个反转控制容器.它创建在一个微内核的基 础之上,这个微内核能够扫描类并且试图找到这些类用到哪些对象引用.对象依赖,然后把这些依赖信 息提供给类使用. 组件(Component):也就是我们通常所说的业务逻辑单元

Asp.net MVC示例项目“Suteki.Shop”分析之ViewData

使用强类型的ViewData好处有许多,比如说在IDE中就会有更好的支持,比如代码提示.同时在View 与Controller之间有更严谨的"约定".在Suteki.Shop项目中作者对强类型的ViewPage引入 是通过MvcContrib实现的,下面就是其ViewPage<T>代码(Suteki.Shop\Views\ViewPage.cs): public class ViewPage<T> : MvcContrib.FluentHtml.ModelVie

Asp.net MVC示例项目“Suteki.Shop”分析之NVelocity模版引擎

在Suteki.Shop中使用了NVeloctiy模版引擎,用于提供可订制的邮件模版.而邮件的功能就是当定单 状态发生变化时,系统会向买家发送邮件通知.其中的邮件信息内容就是采用NVeloctiy的模版(.vm扩 展名)进行订制的. 因为在Sutekie.Shop的最新源码包中只是部分实现了其功能,而全部的功能 还在完善中,所以要运行本文中所说的功能,需要在下面的链接地址中下载其最新程序文件(包括单元 测试文件): http://code.google.com/p/sutekishop/sour

Asp.net MVC示例项目“Suteki.Shop”分析之NHibernate

在Suteki.Shop中内置了提供了基于NHibernate方式的ORM功能,只不过就目前的项目进度还未全部完 成其设计时的构想,另外在单元测试上也没有完整的测试.不过其设计思路还是很有意思的. 就 其将NHibernate引入到项目中的实现方式而言,与Rhino.Commons中所提倡的方式如出一辙,那就是基于 IRepository模式.关于IRepository这个接口的定义在之前的这篇文章中已提到并做了相应说明,所以 这里就不多做解释了. 好了,下面就开始今天的正文. 首先让我们看一下

Asp.net MVC示例项目“Suteki.Shop”分析之数据验证

在Suteki.Shop,实现了自己的数据校验机制,可以说其设计思路还是很有借鉴价值的.而使用这种 机制也很容易在Model中对相应的实体对象(属性)添加校验操作方法.下面就来介绍一下其实现方式. 首先,看一下这样类图: 在Suteki.Shop定 义一个"IValidatingBinder"接口,其派生自IModelBinder: 其接口中定义了一个 重载方法UpdateFrom,其要实现的功能与MVC中UpdateFrom一样,就是自动读取我们在form中定义的有些 元素及其中所包

Asp.net MVC示例项目“Suteki.Shop”分析之Model和Service

在Suteki.Shop中Model的原型是基于Linq to SQL创建的,其dbml文件位于Suteki.Shop\Shop.dbml. 而Suteki.Shop在此文件的基本上,以"partial class "的方式在Suteki.Shop\Model文件夹下 创建了相应的类文件以扩展Shop.dbml中Model类的一些方法和属性声明,如下图: 为了便于 大家理解,下面以Model中的Product.cs为例进行说明. Product是对网站中所销售商品的数据信 息类.在其中

Asp.net MVC示例项目“Suteki.Shop”分析之ModelBinder

在Suteki.Shop中,作者构造了一个ModelBinder基类"DataBinder",其本身继承自 IModelBinder接口,并以此其类派生出其它一些子类类如ProductBinder等等.可以说除了极个别的地方 之外,DataBinder被用于了Suteki.Shop大多数的ModelBinder绑定场景之路. 首先看一下其类图 结构: 作为基类, DataBinder(图中左下方)实现了将HTTP请求过来的数据转换成为模型中相应的类型.其核心方法就是 BindModel