代码改变世界

Caliburn笔记-过滤器管理(IFilterManager)(wpf框架)

2009-12-30 13:40  Clingingboy  阅读(1012)  评论(0编辑  收藏  举报

     过滤器用于装饰对象本身和对象中的方法.如下图

image

具体介绍可见此

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;
}

 

image

过滤器与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,若要这么做的话就需要管理好过滤器的生命周期,或者有意更改生命周期