1

从我所做的阅读中,我希望我能够创建从 OnExceptionAspect 继承的不同方面,这将允许我在我的代码中以不同的方式处理不同的异常。

为此,我创建了两个 Aspect 类,如下所示:

[Serializable]
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class CommonExceptionAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        string msg = string.Format("{0} had an error @ {1}: {2}\n{3}",
        args.Method.Name, DateTime.Now,
        args.Exception.Message, args.Exception.StackTrace);

        Trace.WriteLine(msg);

        if (args.Exception.GetType() != typeof (PppGeneralException))
        {
            throw new Exception("There was a problem");
        }
        else
        {
            args.FlowBehavior = FlowBehavior.RethrowException;
        }
    }
}

另一个方面类:

[Serializable]
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = (MulticastAttributes.Public | MulticastAttributes.NonAbstract | MulticastAttributes.Instance | MulticastAttributes.UserGenerated))] 
public class AuthenticationExceptionAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        string msg = string.Format("{0} had an error @ {1}: {2}\n{3}",
        args.Method.Name, DateTime.Now,
        args.Exception.Message, args.Exception.StackTrace);

        Trace.WriteLine(msg);

        throw new Exception("You are not authorized!");
    }

    public override Type GetExceptionType(System.Reflection.MethodBase targetMethod)
    {
        return typeof(AuthenticationException);
    }
}

我的调用方法如下:

   public void EstablishConnection(string connectionString, DateTime d1, int connections)
    {
        Thread.Sleep(5000);
        if (connectionString.Length > 0)
        {
            throw new ExternalException("This is my external exception");
        }
    }

    public void StopDatabase(string connectionString)
    {
        Thread.Sleep(5000);

        if (connectionString.Length > 0)
        {
            throw new AuthenticationException("This is my detailed exception");
        }
        else
        {
            throw  new ArgumentException("This is just an argument exception");
        }
    }

我在 AssemblyInfo.cs 文件中有以下条目:

[assembly: CommonExceptionAspect(AspectPriority = 3, AttributePriority = 1)]
[assembly: CommonExceptionAspect(AttributeExclude = true, AspectPriority = 3, AttributePriority = 0, AttributeTargetMembers = "ConsoleApplication3.ConnectionManager.StopDatabase", AttributeTargetTypeAttributes = MulticastAttributes.Public, AttributeTargetMemberAttributes = MulticastAttributes.Public, AttributeTargetElements = MulticastTargets.Method)]
[assembly: AuthenticationExceptionAspect(AspectPriority = 1)]

我的期望是,当第一个调用者方法引发“ExternalException”时,“CommonExceptionAspect”的 OnException 方法会处理它。当“AuthenticationException”从第二个调用方方法引发时,“AuthenticationExceptionAspect”的 OnException 方法。

但在这两种情况下,调用都会转到“CommonExceptionAspect”。有人可以指出我做错了什么吗?如果这种理解不正确,并且这种情况完全有可能实现。

提前感谢负载。

4

1 回答 1

0

如果AspectPriority数字较大,则表示将首先应用方面(或更准确地说是转换)。因此,在您的情况下,您正在应用第CommonExceptionAspect一个方面,无论其他方面如何,这个方面都会收到所有异常。

您需要以其他方式设置优先级。

作为旁注 - 多个 OnException(或 OnMethodBoundary)方面的组合不会创建具有多个 catch 语句的单个 try-catch 块,但会创建多个嵌套的 try-catch 块。因此,行为可以不同。

于 2014-11-19T12:38:17.827 回答