2014-11-19 4 views
1

필자가 해본 결과, 다른 예외를 코드에서 다르게 처리 할 수있는 OnExceptionAspect에서 상속받은 다양한 Aspects를 만들 수있을 것으로 기대했습니다.서로 다른 예외를 처리 할 수있는 여러 가지 측면

[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 파일에 다음 항목이 있습니다 :

내 첫 번째 호출자 메서드가 "ExternalException"을 발생 시키면 "CommonExceptionAspect"의 OnException 메서드가이를 처리 할 것으로 기대했습니다. 그리고 두 번째 호출자 메서드에서 "AuthenticationException"이 발생하면 "AuthenticationExceptionAspect"의 OnException 메서드가 호출됩니다.

그러나 두 시나리오 모두에서 호출은 "CommonExceptionAspect"로 이동합니다. 누군가 내가 잘못하고있는 것을 지적 해 주시겠습니까? 이 이해가 부정확하고이 시나리오가 가능한 한 달성 할 수 있다면.

미리 감사드립니다.

+0

StackOverflow에 오신 것을 환영합니다! [해당 제목에 "태그에"태그를 포함해야합니까? "] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-the-titles)를 참조하십시오. 여기서 컨센서스는 다음과 같습니다. "아니, 그들은해서는 안된다". 감사합니다. –

답변

0

의 수가 클수록 숫자가 높을수록 애스펙트 (또는보다 정확하게는 변환)가 먼저 적용된다는 의미입니다. 따라서 귀하의 경우에는 먼저 CommonExceptionAspect을 적용하고이 측면은 다른 측면에 관계없이 모든 예외를 받게됩니다.

다른 방법으로 우선 순위를 설정해야합니다.

여러 개의 OnException (또는 OnMethodBoundary) 애스펙트는 여러 개의 catch 문을 가진 단일 try-catch 블록을 만들지 않지만 여러 개의 중첩 된 try-catch 블록을 만듭니다. 따라서 행동이 다를 수 있습니다.

+0

. 그것은 효과가 있었다. – Jay

+0

또한 AuthenticationExceptionAspect에서 일반적인 예외를 발생 시키면 CommonExceptionAspect에 캐치되어 AuthenticationExceptionAspect에서 발생한 예외에서 전달하려는 실제 정보를 다시 숨 깁니다. CommonExceptionAspect에서 무시할 수있는 특정 유형의 예외를 발생시키고 FlowBehavior를 Rethrow로 설정하면이 문제를 해결할 수 있습니다. 다시 한 번 감사드립니다! – Jay