/// <summary> /// Dispatches a <see cref="Request"/> on the given network. /// </summary> /// <param name="request">Request to be dispatched.</param> /// <param name="networkName">Current network name.</param> /// <returns>DispatchResult with the corresponding result of the dispatching process.</returns> public virtual DispatchResult Dispatch(Request request, string networkName) { IProxyFactory factory = null; if (request.Behavior.ProxyFactoryType == null) { throw new ArgumentNullException("request.Behavior.ProxyFactoryType"); } try { factory = (IProxyFactory)Activator.CreateInstance(request.Behavior.ProxyFactoryType); } catch { return(DispatchResult.Failed); } object onlineProxy = factory.GetOnlineProxy(request, networkName); if (onlineProxy == null) { return(DispatchResult.Failed); } DispatchResult?dispatchResult = null; int retries = 0; try { while (dispatchResult == null) { Exception exception = null; try { retries++; object result = factory.CallOnlineProxyMethod(onlineProxy, request, ref exception); try { // Proxy method call went ok, call the return command InvokeReturnCommand(onlineProxy, request, result); } catch (Exception ex) { if (ex is TargetInvocationException) { throw new ReturnCallbackException(Resources.ExceptionOnReturnCallback + ex.Message, ex.InnerException); } else { throw new ReturnCallbackException(Resources.ExceptionOnReturnCallback + ex.Message, ex); } } dispatchResult = DispatchResult.Succeeded; break; } catch (OnlineProxyException ex) { throw ex.InnerException; } catch (TargetInvocationException ex) { exception = ex.InnerException; } catch (Exception ex) { exception = ex; } if (exception != null) { // Call the exception callback try { switch (InvokeExceptionCommand(request, exception)) { case OnExceptionAction.Dismiss: dispatchResult = DispatchResult.Failed; break; case OnExceptionAction.Retry: if (retries >= request.Behavior.MaxRetries) { dispatchResult = DispatchResult.Failed; } break; } } catch { dispatchResult = DispatchResult.Failed; } } } } finally { factory.ReleaseOnlineProxy(onlineProxy); } return((DispatchResult)dispatchResult); }