反射以查找应用了PostSharp方面的所有方法

本文关键字:方面 有方法 PostSharp 查找 应用 反射 | 更新日期: 2023-09-27 18:16:46

我创建了一个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和IAspectRepositoryService,它们需要最终版本,但我不确定这些是否足够。

编辑:由@Daniel Balas解决。使用这个答案和我在这里找到的信息,我最终得到了一个自定义方面,看起来像这样,并且能够在运行时通过反射检测到:

    [Serializable]
    [MulticastAttributeUsage(PersistMetaData = true)]
    internal class AffectsProgress : OnMethodBoundaryAspect
    {
        public override void OnExit(MethodExecutionArgs args)
        {
            // do all my progress-related stuff here
        }
    }

反射以查找应用了PostSharp方面的所有方法

组播属性默认情况下在组播阶段被删除,所有实例(如果您对所有方法进行组播,则可能有相当多的实例)都在内部传递给方面框架。

您可以告诉多播引擎不要删除元数据,以便您可以在运行时访问该属性。这是这样做的:

[MulticastAttributeUsage(PersistMetaData = true)]

方面属性将出现在它们所应用的声明上(即方法上的MethodLevelAspect,类型上的TypeLevel Aspect,等等)。

方面被PostSharp编织成IL代码,所以在PostSharp完成后处理后,代表方面的属性就消失了。

ReflectionSearch应该在这里有所帮助(我从来没有自己尝试过),因为它说:

这些方法只在构建时可用。

并且在构建时,这是在方面属性消失之前访问它的最后机会。