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();
}
}
我的解决方案中有两个项目:UI
和 UIAppearanceExtensibility
(由 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*"
)]
我有一个简单的方面:
[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();
}
}
我的解决方案中有两个项目:UI
和 UIAppearanceExtensibility
(由 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*"
)]