コード例 #1
0
        private bool HasCachePut(CacheOperationContexts contexts)
        {
            // Evaluate the conditions *without* the result object because we don't have it yet...
            ICollection <CacheOperationContext> cachePutContexts = contexts.Get(typeof(CachePutOperation));
            ICollection <CacheOperationContext> excluded         = new List <CacheOperationContext>();

            foreach (var context in cachePutContexts)
            {
                try
                {
                    if (!context.IsConditionPassing(CacheOperationExpressionEvaluator.NO_RESULT))
                    {
                        excluded.Add(context);
                    }
                }
                catch (Exception e)
                {
                }
            }

            // Check if all puts have been excluded by condition
            return(cachePutContexts.Count != excluded.Count);
        }
コード例 #2
0
        private object Execute(Func <object> invoker, MethodInfo method, CacheOperationContexts contexts)
        {
            //var context = contexts.Get(typeof(CacheableOperation)).FirstOrDefault();
            //if (context!=null&&context.IsConditionPassing(CacheOperationExpressionEvaluator.NO_RESULT))
            //{
            //   var key = context.GenerateKey(CacheOperationExpressionEvaluator.NO_RESULT);
            //   var cache = context.Caches.FirstOrDefault();
            //   if(cache==null) return new object();
            //   return cache.Get<object>(key.ToString(), null);
            //}
            //else
            //{
            //    return invoker();
            //}

            //判断方法返回值是否为异步类型
            var isAsyncReturnType = method.ReturnType.IsAsyncType();
            //返回类型
            var returnType = isAsyncReturnType ? method.ReturnType.GenericTypeArguments.First() : method.ReturnType;

            //先清除符合条件的缓存
            ProcessCacheEvicts(contexts.Get(typeof(CacheEvictOperation)), true,
                               CacheOperationExpressionEvaluator.NO_RESULT);
            //从缓存中查找结果值
            var cacheHit = FindCachedItem(contexts.Get(typeof(CacheableOperation)), returnType);

            // Collect puts from any @Cacheable miss, if no cached item is found
            var cachePutRequests = new List <CachePutRequest>();

            //如果未命中,则收集这个查询
            if (cacheHit == null)
            {
                CollectPutRequests(contexts.Get(typeof(CacheableOperation)),
                                   CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
            }
            //缓存得结果值
            var cacheValue = new object();

            //如果命中,直接获得命中的结果值作为返回值
            if (cacheHit != null && !HasCachePut(contexts))
            {
                // If there are no put requests, just use the cache hit
                cacheValue = cacheHit.Get();
            }
            else
            //如果未命中,则执行具体方法,获得返回值
            {
                var cacheValueInvoker = invoker();
                if (isAsyncReturnType)
                {
                    //如果是异步结果,则获取task里的result
                    var resultProperty = typeof(Task <>).MakeGenericType(returnType).GetProperty("Result");
                    cacheValue = resultProperty?.GetValue(cacheValueInvoker);
                }
                else
                {
                    //同步则直接为结果
                    cacheValue = cacheValueInvoker;
                }
            }

            // 收集所有put的请求
            CollectPutRequests(contexts.Get(typeof(CachePutOperation)), cacheValue, cachePutRequests);

            //执行所有收集到的put请求,无论是CachePut还是Cacheable未命中
            foreach (var putRequest in cachePutRequests)
            {
                putRequest.Apply(cacheValue);
            }

            //执行清除请求
            ProcessCacheEvicts(contexts.Get(typeof(CacheEvictOperation)), false,
                               cacheValue);

            if (isAsyncReturnType)
            {
                //如果是异步方法,需要对结果值进行封装
                var result = typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters)
                             .MakeGenericMethod(returnType).Invoke(null, new object[] { cacheValue });
                return(result);
            }

            return(cacheValue);
        }