public CacheResultInfo(CacheResultAttribute resultInfo, CacheResultItemsAttribute[] itemInfoArray)
 {
     ResultInfo = resultInfo;
     ItemInfoArray = itemInfoArray;
 }
        /// <summary>
        /// Obtains return value either from cache or by invoking target method
        /// and caches it if necessary.
        /// </summary>
        /// <param name="invocation">
        /// The method invocation that is being intercepted.
        /// </param>
        /// <param name="resultInfo">
        /// Attribute specifying where and how to cache return value. Can be <c>null</c>,
        /// in which case no caching of the result as a whole will be performed 
        /// (if the result is collection, individual items could still be cached separately).
        /// </param>
        /// <param name="vars">
        /// Variables for expression evaluation.
        /// </param>
        /// <param name="cacheHit">
        /// Returns <c>true</c> if the return value was found in cache, <c>false</c> otherwise.
        /// </param>
        /// <returns>
        /// Return value for the specified <paramref name="invocation"/>.
        /// </returns>
        private object GetReturnValue(IMethodInvocation invocation, CacheResultAttribute resultInfo, IDictionary vars, out bool cacheHit)
        {
            if (resultInfo != null)
            {
                #region Instrumentation
                bool isLogDebugEnabled = logger.IsDebugEnabled;
                #endregion
                
                AssertUtils.ArgumentNotNull(resultInfo.KeyExpression, "Key", 
                    "The cache attribute is missing the key definition.");

                object returnValue = null;
                object resultKey = resultInfo.KeyExpression.GetValue(null, vars);
                
                ICache cache = GetCache(resultInfo.CacheName);
                returnValue = cache.Get(resultKey);
                cacheHit = (returnValue != null);
                if (!cacheHit)
                {
                    #region Instrumentation
                    if (isLogDebugEnabled)
                    {
                        logger.Debug(String.Format("Object for key [{0}] was not found in cache [{1}]. Proceeding...", resultKey, resultInfo.CacheName));
                    }
                    #endregion

                    returnValue = invocation.Proceed();
                    if (EvalCondition(resultInfo.Condition, resultInfo.ConditionExpression, returnValue, vars))
                    {
                        #region Instrumentation
                        if (isLogDebugEnabled)
                        {
                            logger.Debug(String.Format("Caching object for key [{0}] into cache [{1}].", resultKey, resultInfo.CacheName));
                        }
                        #endregion
                        cache.Insert(resultKey, (returnValue == null) ? NullValue : returnValue, resultInfo.TimeToLiveTimeSpan);
                    }
                }
                else
                {
                    #region Instrumentation
                    if (isLogDebugEnabled)
                    {
                        logger.Debug(String.Format("Object for key [{0}] found in cache [{1}]. Aborting invocation...", resultKey, resultInfo.CacheName));
                    }
                    #endregion
                }

                return (returnValue == NullValue) ? null : returnValue;
            }

            cacheHit = false;
            return invocation.Proceed();
        }