I have an OnMethodBoundary
aspect I created to keep track of progress events in a template method. One of the things that would be useful to know in terms of the overall progress is the number of progress steps that are required by my process before it finishes, i.e. the number of methods tagged with my [AffectsProgress]
attribute.
Rather than hard coding it and having to maintain that as I add and remove methods, I've tried using System.Reflection
to determine that with code like the following (there were many variants I tried):
typeof (MyModuleWithProgressSteps)
.GetMethods(/* whatever BindingFlags I need */)
.SelectMany(x => x.CustomAttributes.Where(attribute => attribute.AttributeType == typeof (AffectsProgress)))
However, even though I was able to see other attributes when I removed the Where
clause, I was unable to find any PostSharp aspects. My naive guess is that PostSharp aspects that interfere with the call stack upon execution aren't actually traditional method attributes and so the System.Reflection
library doesn't see them.
Does anyone know of a way I could get what I'm looking for either with System.Reflection
or with PostSharp itself? I came across ReflectionSearch and IAspectRepositoryService which require the Ultimate edition but I'm not sure if those are sufficient or not.
Edit: Resolved by @Daniel Balas. Using that answer and the information I found here I ended up with a custom aspect that looked like this and was able to be detected at runtime by reflection:
[Serializable]
[MulticastAttributeUsage(PersistMetaData = true)]
internal class AffectsProgress : OnMethodBoundaryAspect
{
public override void OnExit(MethodExecutionArgs args)
{
// do all my progress-related stuff here
}
}
Multicast attributes are by default removed during the multicasting phase and all instances (there can be quite many if you i.e. multicast to all methods) are passed internally to the Aspect Framework.
You can tell the multicast engine not to remove metadata so that you can access the attribute at runtime. This is done like this:
[MulticastAttributeUsage(PersistMetaData = true)]
Aspect attributes will then be present on declarations on which they have been applied on (i.e. MethodLevelAspect on methods, TypeLevel aspect on types, etc.).