예제 #1
0
 public static void PushProxy(object proxy)
 {
     ProxyStack.Push(proxy);
 }
예제 #2
0
        /// <summary>
        ///     Method call wrapper that calls aspects and the intercepted method.
        /// </summary>
        /// <param name="actualMethodInvokerClosure">Intercepted method call wrapped in an interceptor's closure.</param>
        protected void ExecuteMainSequence(Action actualMethodInvokerClosure)
        {
            if (this.isUsed)
            {
                throw new Exception("Same instance of the call interceptor cannot be used more than once.");
            }

            this.isUsed = true;

            this.ReturnedValue            = null;
            this.MethodExecutionException = null;
            this.MethodWasCalled          = false;

            try
            {
#if DEBUG
                if (ProxyStack.Any())
                {
                    Debug.Assert(ProxyStack.Peek() != this);
                }
#endif
                ProxyStack.Push(this);

                try
                {
                    this.CheckForRequiredAspects();

                    this.Step_2_BeforeTryingMethodExec();

                    this.MethodWasCalled = true;

                    try
                    {
                        if (this.CancelInterceptedMethodCall)
                        {
                            // Returned result came from cache.
                            if (this.InterceptedMedthodCallFailed)
                            {
                                // Return cached exception.
                                this.Step_4_Optional_AfterCatchingMethodExecException();
                                throw this.MethodExecutionException;
                            }
                        }
                        else
                        {
                            // Retry loop
                            for (this.AttemptsMade = 1;; this.AttemptsMade++)
                            {
                                try
                                {
                                    actualMethodInvokerClosure.Invoke(); // Step 3 (post-call returned result massaging) is called inside this closure.

                                    this.Step_4_Optional_AfterSuccessfulCallCompletion();

                                    if (this.ShouldRetryCall)
                                    {
                                        this.ShouldRetryCall = false;
                                    }
                                    else
                                    {
                                        break; // success - break retry loop.
                                    }
                                }
                                catch (Exception ex)
                                {
                                    this.MethodExecutionException = ex;
                                    this.Step_4_Optional_AfterCatchingMethodExecException();

                                    if (this.ShouldRetryCall)
                                    {
                                        this.MethodExecutionException = null;
                                        this.ShouldRetryCall          = false;
                                    }
                                    else
                                    {
                                        // No more call attempts - break the retry loop.
                                        if (ex == this.MethodExecutionException)
                                        {
                                            throw;
                                        }

                                        throw this.MethodExecutionException;
                                    }
                                }
                            } // retry loop
                        }
                    }
                    finally
                    {
                        this.Step_5_FinallyAfterMethodExecution();
                    }
                }
                finally
                {
                    // Cleanup phase.
                    if (this.instanceCleanerFunc != null)
                    {
                        try
                        {
                            this.instanceCleanerFunc.Invoke(this.AugmentedClassInstance);
                            this.Step_6_Optional_AfterInstanceCleanup();
                        }
                        finally
                        {
                            if (this.AugmentedClassInstance is IInterceptionContext)
                            {
                                (this.AugmentedClassInstance as IInterceptionContext).Proxy = null;
                            }
                        }
                    }

                    this.Step_7_AfterEverythingSaidAndDone();
                }
            }
            finally
            {
                Proxy top = ProxyStack.Pop();
                Debug.Assert(top == this);
            }
        }