Использование перехвата единства для решения проблемы обработки исключений в качестве сквозной задачи - PullRequest
5 голосов
/ 20 марта 2012

Я создал свое собственное поведение следующим образом:

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. Кто-нибудь может уточнить, почему? Я на самом деле не пытаюсь решить эту проблему, так как есть много способов справиться с исключениями, более того, я не понимаю, что происходит, и мне бы хотелось.

Ответы [ 3 ]

6 голосов
/ 05 апреля 2012

Вы не можете поймать какое-либо исключение, если возникнет Исключение, оно будет частью свойства Исключения 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;
}
1 голос
/ 15 мая 2015

Я думаю, что есть еще один важный момент. Исключение не будет обработано и сохранено в IMethodReturn.Exception, если оно было брошено глубже в поведенческий конвейер . Потому что Unity создает перехваченную оболочку метода, которая является экземпляром InvokeInterceptionBehaviorDelegate, окружая вызов метода блоком try-catch. Но это не относится к вашему методу перехватчика. Вы можете проверить 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 голосов
/ 06 января 2017

Я знаю, что это старый пост, но решение gideon выдает исключительную ссылку Unity исключение .И я хочу обработать Исключение в вызывающем абоненте, а не в Перехвате 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
}
...