2012-03-20 6 views
5

creé mi propio comportamiento de la siguiente manera:unidad para resolver el manejo de excepciones como preocupación transversal

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; } 
} 

} 

lo tengo configurado correctamente para que mi comportamiento es golpeado como se esperaba. Sin embargo, si ocurre alguna excepción en lo que sea getNext(), no golpea mi bloque catch. ¿Alguien puede aclarar por qué? Realmente no estoy buscando resolver el problema ya que hay muchas maneras de lidiar con las excepciones, es más que no entiendo lo que está pasando, y me gustaría.

+0

Qué hacer ¿Ves cuando entras en el depurador? – SLaks

+0

cómo registrar esta interceptación para la implementación de todas mis interfaces? – TotPeRo

Respuesta

6

No se puede detectar ninguna excepción; si se produce una excepción, formará parte del Exception property of IMethodReturn.

así:

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

Acabo de tener un error en ** Unity Framework ** que arroja una * excepción de referencia nula * debido a la devolución * null *. ¿Por qué quieres devolver * null *? Simplemente vuelva a lanzar la * Excepción * con 'ExceptionDispatchInfo.Capture (ret.Exception) .Throw();' –

1

Creo que hay un punto más importante que hacer. La excepción no se manejará y se guardará en IMethodReturn.Exception si se lanzó a más profundidad dentro de behaviors pipeline. Porque Unity crea un contenedor de métodos interceptados, que es la instancia InvokeInterceptionBehaviorDelegate, mediante la invocación del método circundante con el bloque try-catch. Pero ese no es el caso para su método interceptor. Puede consultar el método CreateDelegateImplementation() y la clase InterceptionBehaviorPipeline para obtener más detalles sobre cómo se hace esto.

Si desea procesar excepciones que fueron arrojados desde otra, interceptores más profundas también se puede usar algo como esto:

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

Sé que es una entrada antigua, pero la solución Gideon 's lanzar una Unidad referencia nula Excepción. Y quiero manejar la Excepción en la persona que llama y no en la Intercepción de Unidad.

Aquí es una solución de trabajo que emitir la excepción de la persona que llama y no en el Intercepción:

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; 
} 

Entonces cuando llama a un método interceptado se puede obtener la excepción:

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