postsharp 中的方面多播

aspect multicasting in postsharp

我有一个简单的方面:

[System.Serializable()]
[System.AttributeUsage(System.AttributeTargets.Assembly)]
[PostSharp.Extensibility.MulticastAttributeUsage(PostSharp.Extensibility.MulticastTargets.Method)]
public class NullableMethodCallAspect : PostSharp.Aspects.MethodInterceptionAspect
{

    public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args)
    {
        if (args.Instance != null)
            args.Proceed();
    }

}

我的解决方案中有两个项目:UIUIAppearanceExtensibility(由 UI 引用)。

在第二个中,我声明了一些接口,以便其他开发人员使用它们来根据这些接口创建多个实现。

UI开始,我声明了那些接口的属性,例如IInterface1

因此,在我的 UI 项目(程序集)中,我需要将我的方面应用到对 IInterface1 对象的每次调用...

我已经试过了,但是,它不起作用:

[assembly: UI.Aspects.NullableMethodCallAspect(
    AttributeTargetAssemblies = "UIAppearanceExtensibility",
    AttributeTargetTypes = "UI.Appearance.Extensibility.Triage.*",
    AttributeTargetMembers = "regex: handle*"
)]

在所示示例中,对接口成员的调用将在 UI 程序集中被拦截,但仅当它们通过接口类型的变量访问时才被拦截。

例如:

// Interface in UIAppearanceExtensibility 
public interface IInterface1
{
    void Method1();
}

// Class in UI
public class Class1 : IInterface1
{
    // ...
}

// This usage in UI will be intercepted
IInterface1 i1 = new Class1();
i1.Method1();

// This usage in UI will not be intercepted
Class1 c1 = new Class1();
c1.Method1();

原因是编译器在第二种情况下生成的 IL 代码没有引用 IInterface1 并且 PostSharp 在应用方面时正在寻找 IInterface1 的用法。

在您的情况下,最好将方面应用于 UIAppearanceExtensibility 程序集本身的接口,并将 AttributeInheritance 属性 设置为 MulticastInheritance.Strict。然后该属性将被多播到实现该接口的 类。此用例记录在 Understanding Aspect Inheritance.

// In the UIAppearanceExtensibility project
[assembly: UI.Aspects.NullableMethodCallAspect(
    AttributeInheritance = MulticastInheritance.Strict
    AttributeTargetTypes = "UI.Appearance.Extensibility.Triage.*",
    AttributeTargetMembers = "regex: handle*"
)]