I've a simple aspect:
[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();
}
}
I've two projects inside my solution: UI
and UIAppearanceExtensibility
(this is referenced by UI
).
In the second one, I declare some interfaces in order for other developers to use them for creating several implementations according those interfaces.
From UI
, I declare properties of those interfaces, for example IInterface1
.
So, from my UI project (assembly), I need to apply my aspect to every call to IInterface1
objects...
I've tried that, but, it doesn't work:
[assembly: UI.Aspects.NullableMethodCallAspect(
AttributeTargetAssemblies = "UIAppearanceExtensibility",
AttributeTargetTypes = "UI.Appearance.Extensibility.Triage.*",
AttributeTargetMembers = "regex: handle*"
)]
In the shown example the calls to interface members will be intercepted in the UI assembly, but only when they are accessed through the variable of the interface type.
For example:
// 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();
The reason is that the IL code generated by compiler in the second case does not reference IInterface1
and PostSharp is looking for the usages of IInterface1
when applying the aspect.
In your case it's probably better to apply the aspect to the interfaces in the UIAppearanceExtensibility
assembly itself, and set AttributeInheritance
property to MulticastInheritance.Strict
. The attribute will then be multicast to the classes implementing the interface. This use case is documented in Understanding Aspect Inheritance.
// In the UIAppearanceExtensibility project
[assembly: UI.Aspects.NullableMethodCallAspect(
AttributeInheritance = MulticastInheritance.Strict
AttributeTargetTypes = "UI.Appearance.Extensibility.Triage.*",
AttributeTargetMembers = "regex: handle*"
)]