2012-03-20 66 views
5

我創建了自己的行爲如下:使用Unity攔截解決異常處理等交叉領域

public class BoundaryExceptionHandlingBehavior : IInterceptionBehavior 
{ 


public IEnumerable<Type> GetRequiredInterfaces() 
{ 
    return Type.EmptyTypes; 
} 

public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) 
{ 
    try 
    { 
    return getNext()(input, getNext); 
    } 
    catch (Exception ex) 
    { 
    return null; //this would be something else... 
    } 
} 

public bool WillExecute 
{ 
    get { return true; } 
} 

} 

我正確地把它設置,使預期我的行爲被擊中。但是,如果在getNext()中發生任何異常,它不會觸發我的catch塊。任何人都可以澄清爲什麼?我沒有真正想要解決這個問題,因爲有很多方法來處理異常,更多的是我不明白髮生了什麼,我想。

+0

怎麼辦你在調試器中看到什麼時候? – SLaks 2012-03-20 03:18:05

+0

如何爲我所有的接口實現註冊這個攔截? – TotPeRo 2016-10-14 21:46:07

回答

6

您不能捕捉任何異常,如果發生異常,它將成爲Exception property of IMethodReturn的一部分。

像這樣:

public IMethodReturn Invoke(IMethodInvocation input, 
       GetNextInterceptionBehaviorDelegate getNext) 
{ 
    IMethodReturn ret = getNext()(input, getNext); 
    if(ret.Exception != null) 
    {//the method you intercepted caused an exception 
    //check if it is really a method 
    if (input.MethodBase.MemberType == MemberTypes.Method) 
    { 
     MethodInfo method = (MethodInfo)input.MethodBase; 
     if (method.ReturnType == typeof(void)) 
     {//you should only return null if the method you intercept returns void 
      return null; 
     } 
     //if the method is supposed to return a value type (like int) 
     //returning null causes an exception 
    } 
    } 
    return ret; 
} 
+0

我剛剛在** Unity Framework **中發生錯誤,該錯誤由於返回null *而拋出* null引用異常*。你爲什麼要返回* null *?只需使用ExceptionDispatchInfo.Capture(ret.Exception).Throw();重新拋出* Exception * – 2017-01-06 11:38:45

1

我覺得是讓一個更重要的一點。如果在behaviors pipeline之內投擲得更深,則不會處理異常並將其保存到IMethodReturn.Exception。由於Unity通過使用try-catch塊來圍繞方法調用創建攔截的方法包裝器,即InvokeInterceptionBehaviorDelegate實例。但是攔截器方法並非如此。您可以檢查CreateDelegateImplementation()方法和InterceptionBehaviorPipeline類,以獲取有關如何完成的更多詳細信息。

如果要處理來自其他被拋出的例外,更深層次的攔截器也可以使用這樣的事情:

public IMethodReturn Invoke(IMethodInvocation input, 
          GetNextInterceptionBehaviorDelegate getNext) 
{ 
    try 
    { 
     return InvokeImpl(input, getNext); 
    } 
    catch (Exception exception) 
    { 
     // Process exception and return result 
    } 
} 

private IMethodReturn InvokeImpl(IMethodInvocation input, 
           GetNextInterceptionBehaviorDelegate getNext) 
{ 
    var methodReturn = getNext().Invoke(input, getNext); 
    if (methodReturn.Exception != null) 
     // Process exception and return result 

    return methodReturn; 
} 
0

我知道這是舊的文章,但基甸的解決方案拋出Unity 空引用異常。我想處理調用者中的異常,而不是在統一攔截中。

這裏是拋出異常的調用者,而不是進入攔截工作解決方案:

public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) 
{ 
    IMethodReturn ret = getNext()(input, getNext); 
    if (ret.Exception != null) 
    { 
     // Throw the Exception out of the Unity Interception 
     ExceptionDispatchInfo.Capture(ret.Exception).Throw(); 
    } 

    // Process return result 
    return ret; 
} 

然後當你打電話給你攔截方法,你可以得到例外:

try 
{ 
    // Method intercepted by Unity pipeline 
    InterceptedMethod(); 
} 
catch(Exception e) 
{ 
    //Exception handling 
}