反射以查找应用了 PostSharp 方面的所有方法
Reflection to find all methods with a PostSharp aspect applied
我创建了一个 OnMethodBoundary
方面来跟踪模板方法中的进度事件。就整体进度而言,了解其中一项有用的事情是我的流程在完成之前所需的进度步骤数,即用我的 [AffectsProgress]
属性标记的方法数。
我尝试使用 System.Reflection
来确定它,而不是对其进行硬编码并在添加和删除方法时必须对其进行维护(我尝试了很多变体):
typeof (MyModuleWithProgressSteps)
.GetMethods(/* whatever BindingFlags I need */)
.SelectMany(x => x.CustomAttributes.Where(attribute => attribute.AttributeType == typeof (AffectsProgress)))
然而,即使我在删除 Where
子句时能够看到其他属性,我也无法找到任何 PostSharp 方面。我天真的猜测是,在执行时干扰调用堆栈的 PostSharp 方面实际上并不是传统的方法属性,因此 System.Reflection
库看不到它们。
有谁知道我可以通过 System.Reflection
或 PostSharp 本身获得我正在寻找的东西的方法吗?我发现 ReflectionSearch and IAspectRepositoryService 需要终极版,但我不确定这些是否足够。
编辑:由@Daniel Balas 解决。使用该答案和我找到的信息 here 我最终得到了一个看起来像这样的自定义方面,并且能够在运行时通过反射检测到:
[Serializable]
[MulticastAttributeUsage(PersistMetaData = true)]
internal class AffectsProgress : OnMethodBoundaryAspect
{
public override void OnExit(MethodExecutionArgs args)
{
// do all my progress-related stuff here
}
}
方面由 PostSharp 编织为 IL 代码,因此表示方面的属性在 PostSharp 完成其 post 处理后消失。
ReflectionSearch 应该在这里有所帮助(我从来没有自己尝试过),因为它说:
These methods are only available at build time.
在构建时,这是在属性消失之前访问属性的最后机会。
在多播阶段默认删除多播属性,并且所有实例(如果您将多播到所有方法,则可能有很多)在内部传递给 Aspect Framework。
您可以告诉多播引擎不要删除元数据,以便您可以在运行时访问该属性。这是这样做的:
[MulticastAttributeUsage(PersistMetaData = true)]
然后,方面属性将出现在应用它们的声明中(即方法上的 MethodLevelAspect,类型上的 TypeLevel 方面等)。
我创建了一个 OnMethodBoundary
方面来跟踪模板方法中的进度事件。就整体进度而言,了解其中一项有用的事情是我的流程在完成之前所需的进度步骤数,即用我的 [AffectsProgress]
属性标记的方法数。
我尝试使用 System.Reflection
来确定它,而不是对其进行硬编码并在添加和删除方法时必须对其进行维护(我尝试了很多变体):
typeof (MyModuleWithProgressSteps)
.GetMethods(/* whatever BindingFlags I need */)
.SelectMany(x => x.CustomAttributes.Where(attribute => attribute.AttributeType == typeof (AffectsProgress)))
然而,即使我在删除 Where
子句时能够看到其他属性,我也无法找到任何 PostSharp 方面。我天真的猜测是,在执行时干扰调用堆栈的 PostSharp 方面实际上并不是传统的方法属性,因此 System.Reflection
库看不到它们。
有谁知道我可以通过 System.Reflection
或 PostSharp 本身获得我正在寻找的东西的方法吗?我发现 ReflectionSearch and IAspectRepositoryService 需要终极版,但我不确定这些是否足够。
编辑:由@Daniel Balas 解决。使用该答案和我找到的信息 here 我最终得到了一个看起来像这样的自定义方面,并且能够在运行时通过反射检测到:
[Serializable]
[MulticastAttributeUsage(PersistMetaData = true)]
internal class AffectsProgress : OnMethodBoundaryAspect
{
public override void OnExit(MethodExecutionArgs args)
{
// do all my progress-related stuff here
}
}
方面由 PostSharp 编织为 IL 代码,因此表示方面的属性在 PostSharp 完成其 post 处理后消失。
ReflectionSearch 应该在这里有所帮助(我从来没有自己尝试过),因为它说:
These methods are only available at build time.
在构建时,这是在属性消失之前访问属性的最后机会。
在多播阶段默认删除多播属性,并且所有实例(如果您将多播到所有方法,则可能有很多)在内部传递给 Aspect Framework。
您可以告诉多播引擎不要删除元数据,以便您可以在运行时访问该属性。这是这样做的:
[MulticastAttributeUsage(PersistMetaData = true)]
然后,方面属性将出现在应用它们的声明中(即方法上的 MethodLevelAspect,类型上的 TypeLevel 方面等)。