private async Task Invoke(ICacheProvider cacheProvider, ServiceCacheIntercept attribute, string key, string[] keyVaules, IInvocation invocation)
        {
            switch (attribute.Method)
            {
            case ServiceProxy.Interceptors.Implementation.Metadatas.CachingMethod.Get:
            {
                var retrunValue = await cacheProvider.GetFromCacheFirst(key, async() =>
                    {
                        await invocation.Proceed();
                        return(invocation.ReturnValue);
                    }, invocation.ReturnType, attribute.Time);

                invocation.ReturnValue = retrunValue;
                break;
            }

            default:
            {
                await invocation.Proceed();

                var keys = attribute.CorrespondingKeys.Select(correspondingKey => string.Format(correspondingKey, keyVaules)).ToList();
                keys.ForEach(cacheProvider.RemoveAsync);
                break;
            }
            }
        }
        private async Task CacheIntercept(ServiceCacheIntercept attribute, string key, string[] keyVaules, IInvocation invocation, string l2Key, bool enableL2Cache)
        {
            ICacheProvider cacheProvider = null;

            switch (attribute.Mode)
            {
            case ServiceProxy.Interceptors.Implementation.Metadatas.CacheTargetType.Redis:
            {
                cacheProvider = CacheContainer.GetService <ICacheProvider>(string.Format("{0}.{1}",
                                                                                         attribute.CacheSectionType.ToString(), CacheTargetType.Redis.ToString()));
                break;
            }

            case ServiceProxy.Interceptors.Implementation.Metadatas.CacheTargetType.MemoryCache:
            {
                cacheProvider = CacheContainer.GetService <ICacheProvider>(CacheTargetType.MemoryCache.ToString());
                break;
            }
            }
            if (cacheProvider != null && !enableL2Cache)
            {
                await Invoke(cacheProvider, attribute, key, keyVaules, invocation);
            }
            else if (cacheProvider != null && enableL2Cache)
            {
                var l2CacheProvider = CacheContainer.GetService <ICacheProvider>(CacheTargetType.MemoryCache.ToString());
                if (l2CacheProvider != null)
                {
                    await Invoke(cacheProvider, l2CacheProvider, l2Key, attribute, key, keyVaules, invocation);
                }
            }
        }
        private async Task Invoke(ICacheProvider cacheProvider, ServiceCacheIntercept cacheMetadata, string key, ICacheInvocation invocation)
        {

            switch (cacheMetadata.Method)
            {
                case CachingMethod.Get:
                    {

                        var retrunValue = await cacheProvider.GetFromCacheFirst(key, async () =>
                        {
                            await invocation.Proceed();
                            if (invocation.RemoteInvokeResultMessage.StatusCode == CPlatform.Exceptions.StatusCode.Success)
                            {
                                return invocation.RemoteInvokeResultMessage.Result;
                            }
                            else
                            {
                                throw invocation.RemoteInvokeResultMessage.GetExceptionByStatusCode();
                            }

                        }, invocation.ReturnType, cacheMetadata.Time);

                        if (retrunValue != default)
                        {
                            invocation.ReturnValue = retrunValue;
                            invocation.RemoteInvokeResultMessage = new RemoteInvokeResultMessage() { Result = retrunValue };
                        }
                        break;
                    }
                default:
                    {
                        await invocation.Proceed();
                        var keys = cacheMetadata.CorrespondingKeys.Select(correspondingKey => string.Format(correspondingKey, invocation.CacheKey)).ToList();
                        keys.ForEach(key => {
                            cacheProvider.RemoveAsync(key);
                        });
                        break;
                    }
            }
        }