r>(),
Component.For<IServiceLocator>().Instance(new WindsorServiceLocator (container)),
看来其最终会使用Castle框架所提供的IOC功能。
其实理解上面代码并不难,就是Suteki.Shop以自己实现的FilterUsingAttribute代替了MVC自己的 ActionFilterAttribute, (当然它做的并不彻底,大家会在接下来的内容中看到)。当然有了 FilterUsingAttribute之后,Suteki.Shop并没有直接就去在Action中直接使用它,而是以它派生出了几 个Filter属性:
UnitOfWorkAttribute:项目中大部分Action使用
AuthenticateAttribute:用户信息认证
LoadUsingAttribute
其中 UnitOfWorkAttribute和AuthenticateAttribute被用的最多,下面就分别加以介绍说明。
首先是UnitOfWorkAttribute,其构造方法声明中将UnitOfWorkFilter作为其基类方法的 构造类型,如下:
public class UnitOfWorkAttribute : FilterUsingAttribute
{
public UnitOfWorkAttribute() : base(typeof (UnitOfWorkFilter))
{
}
}
public class UnitOfWorkFilter : IActionFilter
{
private readonly IDataContextProvider provider;
public UnitOfWorkFilter(IDataContextProvider provider)
{
this.provider = provider;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
var context = provider.DataContext;
if (filterContext.Controller.ViewData.ModelState.IsValid)
{
context.SubmitChanges();
}
}
}
其要实现的功能主要 是对用户所做的数据操作进行判断,如果没有发生异常:ModelState.IsValid为True时,则提交所做的 修改到数据库中。
接下来再看一个AuthenticateAttribute,前面说过,其所实现的功能就是对 当前用户身份进行验证,其核心代码如下,因为内容比较简单,大家一看便知。
public class AuthenticateAttribute : FilterUsingAttribute
{
public AuthenticateAttribute() : base(typeof(AuthenticateFilter))
{
Order = 0;
}
}
public class AuthenticateFilter : IAuthorizationFilter
{
private IRepository<User> userRepository;
private IFormsAuthentication formsAuth;
public AuthenticateFilter(IRepository<User> userRepository, IFormsAuthentication formsAuth)
{
this.userRepository = userRepository;
this.formsAuth = formsAuth;
}
public void OnAuthorization (AuthorizationContext filterContext)
{
var context = filterContext.HttpContext;
if(context.User != null && context.User.Identity.IsAuthenticated)
{
var email = context.User.Identity.Name;
var user = userRepository.GetAll().WhereEmailIs(email);
if (user == null)
{
formsAuth.SignOut();
}
else
{
AuthenticateAs(context, user);
return;
}
}
AuthenticateAs (context, User.Guest);
}
private void AuthenticateAs(HttpContextBase context, User user)
{
Thread.CurrentPrincipal = context.User = user;
}
}
当然在本文开篇说过,Suteki.Shop也使用了我们经常用到的方式,即从ActionFilterAttribute继承实现自己的ActionFilter,比如说CopyMessageFromTempDataToViewData(Suteki.Shop\Filters\CopyMessageFromTempDataToViewData.cs),从字面可以看出,其要实现的功能就是把临时数据复制到ViewData中,以便于前台视图显示,下面是其类图:
其实现代码如下:
public class CopyMessageFromTempDataToViewData : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContex
|