过滤器用于装饰对象本身和对象中的方法.如下图
具体介绍可见此
http://caliburn.codeplex.com/wikipage?title=Filters&referringTitle=Documentation
IFilterManager
IFilterManager接口为过滤器管理器,用于存放过滤器接口,每个Action都有一个过滤器管理器
1.IRescue
捕获错误
public class Calculator { [Rescue(Priority=1)] public int Divide(int left, int right) { throw new Exception("error"); return left / right; } }
2.IPreProcessor
在Action触发之前触发或阻止Action触发
3.IPostProcessor
在Action触发之后触发
public class PreProcessorAttribute : Attribute, IPreProcessor { #region IPreProcessor Members public bool AffectsTriggers { get { return true; } } public bool Execute(IRoutedMessage message, IInteractionNode handlingNode, object[] parameters) { Console.WriteLine("PreProcessor"); return true; } #endregion #region IFilter Members public int Priority { get { return 1; } } #endregion } public class PostProcessorAttribute : Attribute, IPostProcessor { #region IPostProcessor Members public void Execute(IRoutedMessage message, IInteractionNode handlingNode, MessageProcessingOutcome outcome) { Console.WriteLine("PostProcessor"); } #endregion #region IFilter Members public int Priority { get; set; } #endregion }
[PreProcessorAttribute()] [PostProcessorAttribute()] public int Divide(int left, int right) { Console.WriteLine("Action"); return left / right; }
过滤器与Action是密切相关的,我们可以来看下Action内部的实现,看下面代码,上面的流程就非常的清晰了
public override void Execute(ActionMessage actionMessage, IInteractionNode handlingNode, object context) { try { var parameters = _messageBinder.DetermineParameters( actionMessage, _requirements, handlingNode, context );foreach (var filter in _filters.PreProcessors){ if (!filter.Execute(actionMessage, handlingNode, parameters)) return; } var outcome = new MessageProcessingOutcome(_method.Invoke(handlingNode.MessageHandler.Unwrap(), parameters),_method.Info.ReturnType, false );foreach (var filter in _filters.PostProcessors){ filter.Execute(actionMessage, handlingNode, outcome); } HandleOutcome(actionMessage, handlingNode, outcome); } catch (Exception ex) {if(!TryApplyRescue(actionMessage, handlingNode, ex))throw; OnCompleted(); } }
可以使用以上特性定义自己需要的过滤器,建议不要重新定义Action,若要这么做的话就需要管理好过滤器的生命周期,或者有意更改生命周期