首页 > 解决方案 > 如何从 PostSharp 事件中获取特定于上下文的数据

问题描述

我正在考虑使用PostSharp它来捕获发生的事件。然而,我看到的一个大问题是Event我系统中的一部分至少是改变元素的主键。

当我定义我的自定义属性时,我可以要求某些数据点,但它们都是static。我可以建立我的属性来知道如何访问 pk 吗?

就像是

[Event(GetPrimaryKey = (Dictionary<string, object> args)=> { return args["UserId"]; })]
public string CreateUser()
{
    ...
}

在这种情况下可以使用

public override void OnSuccess(MethodExecutionArgs args)
{
    var key = this.getPrimaryKey(args.Arguments);
}

标签: c#postsharp

解决方案


这是可能的,但您需要采取一些不同的方法,因为您可以在属性规范中设置的值相当有限。

最好的方法是使用属性标记主键参数,然后在 PostSharp 构建时找到您需要的参数并将其位置存储在方面。然后该方面被序列化,您可以在运行时使用此变量。

[AttributeUsage(AttributeTargets.Parameter)]
public class EventKeyAttribute : Attribute
{
}

[PSerializable]
public class EventAttribute : OnMethodBoundaryAspect
{
    private int keyPosition;

    public override void CompileTimeInitialize( MethodBase method, AspectInfo aspectInfo )
    {
        this.keyPosition = -1;

        // Go through method's arguments and find the key position.
        foreach (var param in method.GetParameters())
        {
            if (param.IsDefined(typeof(EventKeyAttribute)))
            {
                if (this.keyPosition != -1)
                {
                    // Build time error.
                    Message.Write( param, SeverityType.Error, "ERR001", $"Multiple parameters of {method} are marked with [EventKey]." );
                    return;
                }

                this.keyPosition = param.Position;
            }
        }

        if (this.keyPosition == -1)
        {
            // Build time error.
            Message.Write( method, SeverityType.Error, "ERR002", $"No parameter of {method} is marked with [EventKey]." );
        }
    }

    public override void OnSuccess( MethodExecutionArgs args )
    {
        Console.WriteLine( $"Key is: {args.Arguments[this.keyPosition]}" );
    }
}

之后,您可以简单地在方法上应用这两个属性:

[Event]
static void Foo(int a, [EventKey]int b, int c)
{
}

推荐阅读