Различные аспекты для обработки различных исключений
Из прочитанного мною чтения я ожидал, что смогу создать разные аспекты, унаследованные от 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", метод OnException в "CommonExceptionAspect" будет обрабатывать его. И когда "AuthenticationException" был вызван из второго метода вызывающего, OnException метод "AuthenticationExceptionAspect".
Но в обоих сценариях вызов переходит к "CommonExceptionAspect". Может ли кто-нибудь указать мне, что я делаю неправильно? Если это понимание неверно, и если этот сценарий вообще возможно достичь.
Спасибо загружает заранее.
1 ответ
В случае AspectPriority
большее число означает, что аспект (или, точнее, преобразование) будет применен первым. Поэтому в вашем случае вы применяете CommonExceptionAspect
во-первых, и этот аспект получит все исключения независимо от другого аспекта.
Вы должны установить приоритеты наоборот.
В качестве sidenote - состав нескольких аспектов OnException (или OnMethodBoundary) не создает один блок try-catch с несколькими операторами catch, но создает несколько вложенных блоков try-catch. Таким образом, поведение может быть разным.