【问题标题】:Reflection to find all methods with a PostSharp aspect applied反射以查找应用了 PostSharp 方面的所有方法
【发布时间】:2015-10-09 20:16:26
【问题描述】:

我创建了一个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 本身获得我正在寻找的东西?我遇到了ReflectionSearchIAspectRepositoryService,它们需要终极版,但我不确定这些是否足够。

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

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

【问题讨论】:

    标签: c# reflection postsharp


    【解决方案1】:

    默认情况下,在多播阶段删除多播属性,并且所有实例(如果您将多播到所有方法,则可能有很多)在内部传递给 Aspect Framework。

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

    [MulticastAttributeUsage(PersistMetaData = true)]
    

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

    【讨论】:

    • 我现在要试试这个。这看起来很有希望。
    • 哇哦!这与宣传的完全一样,完美地满足了我的需求。非常感谢。
    【解决方案2】:

    方面由 PostSharp 编织为 IL 代码,因此表示方面的属性在 PostSharp 完成后处理后消失了。

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

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

    在构建时,这是在外观属性消失之前访问它的最后机会。

    【讨论】:

    • 感谢您的回答。似乎为自动代码修改添加预构建步骤或为反射目的使用方法命名约定是硬编码的唯一替代方案。奇怪的是,硬编码似乎是这里最干净的方法,因为一旦流程完全充实,进度步骤的数量就不会发生太大变化。
    • @S.C.好吧,我不喜欢硬编码,但也许你可以做一个预构建步骤来计算方面的数量并修改你的硬编码值。
    • 非常同意,我已经完成了自动代码生成/修改的工作,但是没有 PostSharp Ultimate,我只能将文本处理作为计算方面的最佳方式。虽然这是相当直截了当的,但注释掉的方面、任何继承这一点的人的基本原理文档,以及这些方面的其他细微差别,我担心从长远来看,自动计数代码的维护风险要比一个很少改变的常量风险更大。我也在考虑这个方面的方案,它可以嵌入一些我可以通过反射找到的东西,但还没有具体的东西。
    • 我想还有一个选项冗余香草属性仅用于反射目的。不过,除非我离开 AOP,否则听起来似乎没有一个优雅的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多