private CacheParameterInfo GetCacheParameterInfo(MethodInfo method)
 {
     CacheParameterInfo cpi = (CacheParameterInfo)_cacheParameterInfoCache[method];
     if (cpi == null)
     {
         ParameterInfo[] parameters = method.GetParameters();
         CacheParameterAttribute[][] parameterInfos = new CacheParameterAttribute[parameters.Length][];
         for (int i = 0; i < parameters.Length; i++)
         {
             ParameterInfo p = parameters[i];
             CacheParameterAttribute[] paramInfoArray = (CacheParameterAttribute[])GetCustomAttributes(p, typeof(CacheParameterAttribute));
             parameterInfos[i] = paramInfoArray;
         }
         cpi = new CacheParameterInfo(parameters, parameterInfos);
         _cacheParameterInfoCache[method] = cpi;
     }
     return cpi;
 }
        private CacheParameterInfo GetCacheParameterInfo(MethodInfo method)
        {
            CacheParameterInfo cpi = (CacheParameterInfo)_cacheParameterInfoCache[method];

            if (cpi == null)
            {
                ParameterInfo[]             parameters     = method.GetParameters();
                CacheParameterAttribute[][] parameterInfos = new CacheParameterAttribute[parameters.Length][];
                for (int i = 0; i < parameters.Length; i++)
                {
                    ParameterInfo             p = parameters[i];
                    CacheParameterAttribute[] paramInfoArray = (CacheParameterAttribute[])GetCustomAttributes(p, typeof(CacheParameterAttribute));
                    parameterInfos[i] = paramInfoArray;
                }
                cpi = new CacheParameterInfo(parameters, parameterInfos);
                _cacheParameterInfoCache[method] = cpi;
            }
            return(cpi);
        }
        /// <summary>
        /// Executes after target <paramref name="method"/>
        /// returns <b>successfully</b>.
        /// </summary>
        /// <remarks>
        /// <p>
        /// Note that the supplied <paramref name="returnValue"/> <b>cannot</b>
        /// be changed by this type of advice... use the around advice type
        /// (<see cref="AopAlliance.Intercept.IMethodInterceptor"/>) if you
        /// need to change the return value of an advised method invocation.
        /// The data encapsulated by the supplied <paramref name="returnValue"/>
        /// can of course be modified though.
        /// </p>
        /// </remarks>
        /// <param name="returnValue">
        /// The value returned by the <paramref name="target"/>.
        /// </param>
        /// <param name="method">The intecepted method.</param>
        /// <param name="arguments">The intercepted method's arguments.</param>
        /// <param name="target">The target object.</param>
        /// <seealso cref="AopAlliance.Intercept.IMethodInterceptor.Invoke"/>
        public void AfterReturning(object returnValue, MethodInfo method, object[] arguments, object target)
        {
            #region Instrumentation
            bool isLogDebugEnabled = logger.IsDebugEnabled;
            #endregion

            CacheParameterInfo          cpi = GetCacheParameterInfo(method);
            CacheParameterAttribute[][] cacheParameterAttributes = cpi.CacheParameterAttributes;

            if (cacheParameterAttributes.Length > 0)
            {
                IDictionary vars = PrepareVariables(method, arguments);
                for (int i = 0; i < cacheParameterAttributes.Length; i++)
                {
                    foreach (CacheParameterAttribute paramInfo in cacheParameterAttributes[i])
                    {
                        AssertUtils.ArgumentNotNull(paramInfo.KeyExpression, "Key",
                                                    "The cache attribute is missing the key definition.");

                        if (EvalCondition(paramInfo.Condition, paramInfo.ConditionExpression, arguments[i], vars))
                        {
                            ICache cache = GetCache(paramInfo.CacheName);

                            object key = paramInfo.KeyExpression.GetValue(arguments[i], vars);

                            #region Instrumentation
                            if (isLogDebugEnabled)
                            {
                                logger.Debug(string.Format("Caching parameter for key [{0}] into cache [{1}].", key, paramInfo.CacheName));
                            }
                            #endregion

                            cache.Insert(key, arguments[i], paramInfo.TimeToLiveTimeSpan);
                        }
                    }
                }
            }
        }