代码改变世界

[渣译文]Ninject:Dependency injection for filters

2012-08-06 16:58  Bce  阅读(874)  评论(0编辑  收藏  举报

咱鸟语很差,文采为0,重在概述,请多包涵...

使用新版的Ninject MVC3时发现过滤器的DI跟原来(kernel.BindFilter)不一样了,某度上没找到中文的,遂摸到Ninject老家找到相关文档,看了半天,干脆在这里留个底,方便自己将来回味,也给后来人指个路...写到一半突发奇想,既然文言文咱写不好,干脆写个口语卖萌的吧.....想看渣文言文的同学请反白...

环境:MVC3 + Ninject 3.0.1.10 + Ninject.MVC3 3.0.0.6 

Dependency injection for filters

依赖注入到MVC过滤器

MVC3 introduced a completely new pattern to configure filters for controllers and its actions. While injection of filter attributes is still supported it is recommended using this new pattern for filter configuration because it has the advantage to support constructor injection and does not require the InjectAttribute anymore.

MVC3使用了全新的模式来配置控制器和动作上的过滤器。虽然过滤器特性注入依然被支持,但是我们建议使用新模式来配置过滤器。因为它具有支持构造函数注入的优势,不再需要注入特性了。

新的N-MVC3用了新配置模式啦,原来的不管用鸟,新配置模式支持构造函数注入,无需注入特性鸟...

First of all you have to create your filter class by implementing one of the filter interfaces e.g. IActionFilter. All the dependencies are added to the constructor. The following example of a logging filter has a logger as dependency and can be configured with the level that is used to log.

首先,你需要建立一个实现了过滤器接口(如IActionFilter)的过滤器类,将依赖项添加到构造函数中。下面的例子实现了一个日志过滤器,其中包含一个Log依赖项,以及用于记录日志的级别。

建一个实现了过滤器接口的过滤器类,给你想注入的东东扔到构造函数里面,这个例子中有日志及级别依赖。

 1 public class LogFilter : IActionFilter
 2 {
 3     private readonly ILog log;
 4     private readonly Level logLevel;
 5  
 6     public LogFilter(ILog log, Level logLevel)
 7     {
 8         this.log = log;
 9         this.logLevel = logLevel;
10     }
11  
12     public void OnActionExecuting(ActionExecutingContext filterContext)
13     {
14         var message = string.Format(
15                 CultureInfo.InvariantCulture,
16                 "Executing action {0}.{1}",
17                 filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
18                 filterContext.ActionDescriptor.ActionName),
19         this.log.Logger.Log(typeof(LogFilter), this.logLevel, message, null);
20     }
21  
22     public void OnActionExecuted(ActionExecutedContext filterContext)
23     {
24         var message = string.Format(
25                 CultureInfo.InvariantCulture,
26                 "Executed action {0}.{1}",
27                 filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
28                 filterContext.ActionDescriptor.ActionName),
29         this.log.Logger.Log(typeof(LogFilter), this.logLevel, message, null);
30     }
31 }

嗯,C#用户应该都能看懂这个过滤器想干嘛...

To apply this filter to an action or controller we need to specify a binding. But unlike other bindings, filters require that BindFilter is used instead of the normal Bind. Additionally, the type of the filter you have to specify the filter scope and the filter order. More information about these two parameters can be found "Brad Wilsons Blog":http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html.

In the example below the LogFilter is applied to every action and configured with the log level info.

要应用这个过滤器到控制器或动作,我们需要指定一个绑定。但是不像其他的绑定,旧的BindFilter 绑定方法被换为Bind方法。另外,你必须指定过滤器的作用域及过滤顺序。关于这两个参数的更多信息,请参见Brad Wilsons的博客。

下面的例子中,日志过滤器被应用到控制器上的每个动作中并配置日志级别信息。(构造器注入)

想给这个过滤器弄控制器上面去,旧的BindFiler方法不管用了,需要模块绑定啦。绑定的时候你得指定着过滤器的作用域跟执行顺序,想看这哥俩更多信息的,请猛击布拉德威尔逊老湿的博客文(见上)。

下面代码中,日志过滤器被注册到每一个控制器上,同时配置了日志级别信息。(构造器注入)

 1 public class LoggingModule : NinjectModule
 2 {
 3     public override void Load()
 4     {
 5         this.Bind<ILog>().ToMethod(GetLogger);
 6         this.BindFilter<LogFilter>(FilterScope.Controller, 0)
 7             .WithConstructorArgument("logLevel", Level.Info);
 8     }
 9  
10     private static ILog GetLogger(IContext ctx)
11     {
12         var filterContext = ctx.Request.ParentRequest.Parameters
13                       .OfType<FilterContextParameter>().SingleOrDefault();
14         return LogManager.GetLogger(filterContext == null ?
15             ctx.Request.Target.Member.DeclaringType :
16             filterContext.ActionDescriptor.ControllerDescriptor.ControllerType);
17     }
18 }

Further Information on this topic:

更多信息请参见:

过滤器条件绑定

过滤器配置

更多相关信息请猛击:过滤器条件绑定,过滤器配置(见上)

原文:

Dependency injection for filters

补:找不到BindFilter的同学,请using Ninject.Web.Mvc.FilterBindingSyntax;