【问题标题】:PostSharp: Applying Advice to External TypePostSharp:将建议应用于外部类型
【发布时间】:2017-01-06 01:50:27
【问题描述】:

我正在尝试使用 PostSharp 4.3.24 在外部/第 3 方程序集中的调用站点切入点应用一些建议,但我遇到了一些问题。在最简单的示例中,我试图记录有关应用程序执行的所有 SQL 的一些信息。我的方法是将OnMethodBoundaryAdvice 应用于所有SQLCommand.Execute* 方法(我们不使用BeginExecute* 方法提供的遗留异步模式,所以我故意不包括它们)。我已经尝试使用 PostSharp 解决方案配置文件(MySolution.pssln 文件)的 Multicast 部分以及以下等效的程序集范围的多播属性应用程序:

[assembly:Blah.Telemetry.Aspects.SqlCommandTelemetryAspect(
    AttributeTargetAssemblies = "System.Data", 
    AttributeTargetTypes = "System.Data.SqlClient.SqlCommand", 
    AttributeTargetMembers = "Execute*"
)]

我的 Aspect 声明目前如下所示:

[MulticastAttributeUsage(AllowExternalAssemblies = true, Inheritance = MulticastInheritance.Multicast)]
[PSerializable]
public sealed class SqlCommandTelemetryAspect : OnMethodBoundaryAspect { /*...*/ }

我在 MulticastAttributeUsage 中尝试了目标类型、继承值等的各种组合,但每次都得到同样令人困惑的结果。

我遇到的问题是该建议仅适用于单个 SqlCommand 方法 (ExecuteReader)。我还需要将它应用于所有其他 Execute 方法(例如,ExecuteNonQuery)和所有重载。我还尝试定位DbCommand.Execute*,其中包含其中一些重载的抽象定义。当我直接标记ExecuteNonQuery(而不是使用通配符或正则表达式)时,我收到以下警告,暗示没有应用任何建议(反编译证实了这一点):

POSTSHARP : postsharp warning PS0131: The project 'Blah.Framework.dll' does not contain any aspect or other transformation[...]

我是不是做错了什么,或者这可能是 PostSharp 中的一个错误?

【问题讨论】:

  • 在调用点切入点应用方面时,您需要注意 C# 编译器如何发出该方法调用。在这种情况下,它是对System.Data.Common.DbCommand.ExecuteNonQuery() 的虚拟调用。但是这里的另一个问题是OnMethodBoundaryAspect 不能应用于抽象方法。虽然在将切面应用到方法主体时这个限制是正确的,但对于调用站点切入点来说,解除它也是有意义的。一旦我们获得有关此问题的更多信息,我们会尽快与您联系。
  • @AlexD 啊,我明白了;谢谢(你的)信息。因此,它对调用站点应用相同的约束,就像在声明切入点处编织一样。我有点想这可能与外部编织似乎是对最初不是为外部目标设计的东西的扩展有关。同时还有另一种方法来声明调用站点切入点吗?我正在尝试在工作项目中使用它,这是展示 AOP 节省时间的一个重要近期目标
  • @AlexD 抱歉,也许这不是问这个问题的最佳地点,但我认为我们现在刚刚获得许可,所以我还没有获得正确支持渠道所需的信息
  • 没问题,我们也会监控关于 SO 的问题。响应时间可能会更慢。无论如何,没有其他方法可以为调用站点切入点提供建议。我们将实施一个修复程序,以启用一些具有抽象方法目标的用例。
  • @AlexD 太好了,谢谢。是否有问题跟踪器或我可以关注的地方以查看何时可以开始使用此修复程序?现在假期结束了,我会试着弄清楚我们的许可在哪里等等,但是我在基于 project.json 的 csproj 也遇到了一些问题,我想知道我是否可以在任何地方看到有关发布时间表之类的信息?再次感谢

标签: c# .net aop postsharp


【解决方案1】:

相关错误已在 PostSharp 4.3.26 中修复。现在可以使用方面提供程序将 OnMethodBoundary 和 MethodInterception 方面应用于外部程序集中的抽象方法。

例如:

[assembly:MyAspectProvider(
    AttributeTargetAssemblies = "System.Data", 
    AttributeTargetTypes = "System.Data.Common.DbCommand", 
    AttributeTargetMembers = "Execute*"
)]

[PSerializable]
public class MyAspectProvider : MethodLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        yield return new AspectInstance(targetElement, new MyAspect());
    }
}

[PSerializable]
public class MyAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        // ...
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 2015-11-23
    • 1970-01-01
    相关资源
    最近更新 更多