public ExecutedInfo(object invokingTarget, MethodInfo method, object[] arguments, object returnedValue, ReturnedValueSources source)
 {
     InvokingTarget = invokingTarget;
     Method         = method;
     Arguments      = arguments;
     ReturnedValue  = returnedValue;
     Source         = source;
 }
        public void Intercept(IInvocation invocation)
        {
            MethodInfo           methodInfo;
            ReturnedValueSources source = ReturnedValueSources.OriginalMethod;

            object invokingTarget = invocation.InvocationTarget;

            methodInfo = invocation.MethodInvocationTarget?.GetBaseDefinition();
            if (methodInfo == null)
            {
                methodInfo = invocation.Method.GetBaseDefinition();
            }

            var proxies = this.proxyInfo.ProxyOnClass;
            IEnumerable <IProxy> proxiesOnMethod = this.proxyInfo
                                                   .GetProxiesOnMethod(methodInfo);

            proxies = proxies.Concat(proxiesOnMethod).ToList();

            ExecutingInfo executingInfo = new ExecutingInfo(invokingTarget, methodInfo, invocation.Arguments, invocation);

            foreach (IProxy proxy in proxies)
            {
                proxy.OnExecuting(executingInfo);
            }

            if (executingInfo.SkipExecuteOriginalMethod)
            {
                invocation.ReturnValue = executingInfo.ReturnedValue;
                source = ReturnedValueSources.Proxy;
            }
            else
            {
                try
                {
                    invocation.Proceed();
                }
                catch (Exception ex)
                {
                    ExecuteErrorInfo executeErrorInfo = new ExecuteErrorInfo(invokingTarget, methodInfo, invocation.Arguments, ex);
                    foreach (IProxy proxy in proxies)
                    {
                        proxy.OnExecuteError(executeErrorInfo);
                    }

                    if (executeErrorInfo.PreventThrow)
                    {
                        return;
                    }

                    throw;
                }
            }

            ExecutedInfo executedInfo = new ExecutedInfo(invokingTarget, methodInfo, invocation.Arguments, invocation.ReturnValue, source);

            foreach (IProxy proxy in proxies)
            {
                proxy.OnExecuted(executedInfo);
            }
        }