/// <summary> /// Implement this method to perform extra treatments before and after /// the call to the supplied <paramref name="invocation"/>. /// </summary> /// <param name="invocation">The method invocation that is being intercepted.</param> /// <returns> /// The result of the call to the /// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/> method of /// the supplied <paramref name="invocation"/>; this return value may /// well have been intercepted by the interceptor. /// </returns> /// <remarks> /// <p> /// Polite implementations would certainly like to invoke /// <see cref="AopAlliance.Intercept.IJoinpoint.Proceed"/>. /// </p> /// </remarks> /// <exception cref="System.Exception"> /// If any of the interceptors in the chain or the target object itself /// throws an exception. /// </exception> public override object Invoke(IMethodInvocation invocation) { IDictionary <string, object> callContextDictionary = new Dictionary <string, object>(); callContextDictionary.Add("method", invocation.Method); callContextDictionary.Add("args", invocation.Arguments); callContextDictionary.Add("target", invocation.Target); int numAttempts = 0; object returnVal = null; do { try { returnVal = invocation.Proceed(); break; } catch (Exception ex) { callContextDictionary["e"] = ex; if (retryExceptionHandler.CanHandleException(ex, callContextDictionary)) { numAttempts++; if (numAttempts == retryExceptionHandler.MaximumRetryCount) { throw; } else { if (log.IsTraceEnabled) { log.Trace("Retrying " + invocation.Method.Name); } callContextDictionary["n"] = numAttempts; Sleep(retryExceptionHandler, callContextDictionary, sleepHandler); } } else { throw; } } } while (numAttempts <= retryExceptionHandler.MaximumRetryCount); log.Debug("Invoked successfully after " + numAttempts + " attempt(s)"); return(returnVal); }