PostSharp MethodExecutionTag在方面丢失

凯尔门德

我写了2个拦截,其中1个是通过论证验证,另一个是错误处理。

拦截#1引发错误(按预期),并将自定义对象附加到MethodExecutionArgs.MethodExecutionTag

    public class ValidateArguementAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
            ...
            var state = new ExecutionState
            {
                ReturnExactErrorMessage = true,
            };
            args.MethodExecutionTag = state;

            throw new ArgumentException(errMsgs.ToString());

但是,此MethodExecutionTag在错误处理中丢失。

    public class ExceptionHandlingWithResponseAttribute : ExceptionHandlingAttribute
{
    public override void OnException(MethodExecutionArgs args)
    {
        base.OnException(args);

        ExecutionState state = args.MethodExecutionTag as ExecutionState;
        if (state != null)
        {
          // as debugging, expected to be here, but it's not
        }

我对MethodExecutionArgs.GetHashCode()进行了简单检查,以获取不同的值。

我有一个针对Web Api应用程序设计的类似程序,它可以按预期工作,尽管我无法调试它,因为我正在通过单元测试进行测试。

这是某种错误,还是我该如何解决?

雅库布·林哈特(Jakub Linhart)

这是设计使然。执行标签在各个方面之间是隔离的。

假设您有一个事务和一个缓存方面。两者都在OnEntry中设置执行标签,并尝试在OnExit中检索它。事务方面的标签被缓存方面覆盖,这会造成严重的混乱。

需要隔离以避免类似这样的令人讨厌的事情。

解决方案可能是将这两个方面合并为一个:

public class ValidateArguementAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
            ...
            var state = new ExecutionState
            {
                ReturnExactErrorMessage = true,
            };
            args.MethodExecutionTag = state;

            throw new ArgumentException(errMsgs.ToString());
    }

    public override void OnException(MethodExecutionArgs args)
    {
        base.OnException(args);

        ExecutionState state = args.MethodExecutionTag as ExecutionState;
        if (state != null)
        {
          // as debugging, expected to be here, but it's not
        }
    }
}

或者,可以直接处理验证结果,而不用抛出异常。

UPDATE(基于Kelmen的自定义异常的想法):

public class ValidationException : Exception
{
    public ExecutionState State { get; private set; }

    public ValidationException(ExecutionState state)
    {
        State = state;
    }
}

[Serializable]
public class ValidateArguementAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        var state = new ExecutionState
        {
            ReturnExactErrorMessage = true,
        };

        throw new ValidationException(state);
    }
}

[Serializable]
public class ExceptionHandlingWithResponseAttribute : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        base.OnException(args);

        ValidationException validationException = args.Exception as ValidationException;
        if (validationException != null)
        {
            // handle the exception
        }
        else
        {
            // just rethrow
            args.FlowBehavior = FlowBehavior.RethrowException;
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章