首页 > 解决方案 > 如何在 PostSharp 中拦截对 ICommand.Execute 的调用?

问题描述

我是 PostSharp 的新手,我希望它在我的 MVVM 应用程序中跟踪 GUI 交互。这个想法是用来拦截对'方法的OnMethodBoundaryAspect调用。ICommandExecute

将我的方面应用到我的 RelayCommand 实现的Execute方法时,拦截有效,但我无法从中获得任何上下文 - 我只能看到RelayCommandand Execute,这不是很有帮助。

我真正想要的是ICommand属性的名称和包含的类。我试过这个:

[assembly: PerformanceLog(AttributeTargetTypes = "System.Windows.Input.ICommand",
    AttributeInheritance = MulticastInheritance.Multicast)]

但这不起作用。我想我错过了一些明显的东西?

标签: tracepostsharp

解决方案


如果您需要拦截来自另一个程序集的声明,例如ICommand.Execute,您需要指定目标程序集(在这种情况下为 IIRC WindowsBase,即TargetAssembly="WindowsBase")。但是,这会使您陷入比在RelayCommand.Execute方法上应用方面时更糟糕的情况。由于 PostSharp 仅转换当前程序集,ICommand.Execute因此只会在您的程序集中和可能调用该命令的 PresentationFramework 代码中拦截调用。

由于您需要将您的ICommand属性与调用者相关联,因此您需要在创建 RelayCommand 后将上下文传递到字段/属性中。

如果您的代码如下所示:

public class Test
{
    public RelayCommand _myCommand;
    public ICommand MyCommand => this._myCommand;

    public Test()
    {
        this._myCommand = new RelayCommand(() => this.ExecuteMyCommand());
        // ...
    }

    // ...
}

最简单的方法似乎是使用LocationInterceptionAspecton _myCommand(以及所有其他RelayCommand类型的字段),当_myCommand设置时,您会将有关字段的信息(可通过 LocationInterceptionArgs 访问)推送到 RelayCommand 的实例中(使用您将从中读取的内部属性您的 PerformanceLog 方面)。

类似的方法是在 MyCommand 的 getter 的拦截中推送信息。

应用这种拦截方面的最佳方法可能是在任何地方多播它,并使用一种CompileTimeValidate方法来识别 ICommand/RelayCommand 类型的目标并拒绝(返回 false)所有其他声明。


推荐阅读