简体   繁体   English

使用PostSharp包装方法调用

[英]Wrapping method call with PostSharp

Is there any way to wrap a method call with PostSharp? 有什么办法可以用PostSharp包装方法调用吗? I have to add code around/outside a specific call. 我必须在特定呼叫周围/外部添加代码。

The OnMethodBound add the code inside the specified method and the MethodInterception aspect redirects the call to the aspect, but I have to to add code outside the call. OnMethodBound将代码添加到指定方法内部 ,而MethodInterception方面将调用重定向到该方面,但是我必须在调用外部添加代码。

Example: Without aspect: 示例:无方面:

...
call();
...

With aspect: 搭配方面:

beforePart();
call();
afterPart();

Currently, the only scenario in which PostSharp weaves the aspect around the call site is when you apply that aspect to a method in the referenced assembly. 当前,PostSharp在调用站点周围编织方面的唯一方案是将方面应用于引用程序集中的方法。

When applying an aspect in your project, you can set the name of the external assembly in the AttributeTargetAssemblies property. 在项目中应用方面时,可以在AttributeTargetAssemblies属性中设置外部程序集的名称。

[Log(AttributeTargetAssemblies = "SomeLibrary", ...)]

PostSharp, of course, will not modify the existing external assembly, instead it will weave the aspect in your project's assembly around the calls to the referenced assembly. 当然,PostSharp不会修改现有的外部程序集,而是会在对引用程序集的调用周围编织项目程序集中的方面。

Applying the aspect to the calls of the methods from the same assembly is not currently supported. 当前不支持将方面应用于来自同一程序集的方法的调用。 In most scenarios this is not required, or there should be a reasonable workaround. 在大多数情况下,这不是必需的,或者应该有一个合理的解决方法。

Maybe we'll be able to solve this if you provide more details about your synchronized method and why it's not possible to use method interception. 如果您提供有关同步方法的更多详细信息以及为什么无法使用方法拦截的信息,也许我们将能够解决此问题。

Update. 更新。

The possible workaround is to introduce the synchronization locks using aspects. 可能的解决方法是使用方面引入同步锁。 You can write a custom OnMethodBoundaryAspect or use SynchronizedAttribute from the Threading Pattern Library. 您可以编写自定义OnMethodBoundaryAspect或使用线程模式库中的SynchronizedAttribute

Then you can use Aspect Dependency or Aspect Priority to make sure that the measuring aspect is introduced before the threading aspect. 然后,您可以使用Aspect Dependency或Aspect Priority来确保在线程方面之前引入了测量方面。 This way the behavior will be the same as when introducing the measuring aspect around the call site. 这样,行为将与在呼叫站点周围引入测量方面时相同。

[Serializable]
[AspectTypeDependency(AspectDependencyAction.Order,
                      AspectDependencyPosition.Before,
                      typeof(SynchronizedAttribute))]
public class MeasureTimeAttribute : OnMethodBoundaryAspect
{
    // ...
}

I had similar requirement and I wrote a logging aspect for all database calls I make with external library which is Dapper. 我有类似的要求,并且为使用外部库Dapper进行的所有数据库调用编写了日志记录方面。 I created an aspect: 我创建了一个方面:

[MulticastAttributeUsage(MulticastTargets.Method)]
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public sealed class SqlLogger : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs args)
    {
        // logging code goes here

        base.OnInvoke(args);
    }
}

And then I registered it on assembly level: 然后我在组装级别注册了它:

[assembly: SqlLogger(AttributeTargetAssemblies = "Dapper", AttributePriority = 1)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM