public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptorDelegate getNext)
            {
                string cacheRegion = GetCacheRegion(input.MethodBase);
                string cacheKey    = _cachingAttribute.CacheKey;

                if (string.IsNullOrEmpty(cacheKey))
                {
                    cacheKey = CreateCacheKey(input);
                }
                IMethodReturn realReturn;

                switch (_cachingAttribute.Method)
                {
                case CachingAttribute.CachingMethod.Get:
                    if (TargetMethodReturnsVoid(input))
                    {
                        return(getNext()(input, getNext));
                    }

                    var cache = this.GetOrBuildCache(cacheRegion);

                    var cachedResult = (object[])cache.Get(cacheKey);
                    if (cachedResult == null)
                    {
                        realReturn = getNext()(input, getNext);
                        cache.Put(cacheKey, new object[] { realReturn.ReturnValue, realReturn.Outputs });

                        return(realReturn);
                    }
                    else
                    {
                        var           outputs      = (cachedResult[1] as IParameterCollection).Cast <object>().ToArray();
                        IMethodReturn cachedReturn = input.CreateMethodReturn(cachedResult[0], outputs);
                        return(cachedReturn);
                    }

                case CachingAttribute.CachingMethod.Put:
                    if (TargetMethodReturnsVoid(input))
                    {
                        return(getNext()(input, getNext));
                    }

                    IMethodReturn methodReturn = getNext().Invoke(input, getNext);
                    this.GetOrBuildCache(cacheRegion).Put(cacheKey, new object[] { methodReturn.ReturnValue, methodReturn.Outputs });

                    return(methodReturn);

                case CachingAttribute.CachingMethod.Remove:
                    foreach (var region in _cachingAttribute.RelatedAreas)
                    {
                        this.GetOrBuildCache(region).Clear();
                    }
                    return(getNext().Invoke(input, getNext));
                }

                return(getNext().Invoke(input, getNext));
            }
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptorDelegate getNext)
            {
                string cacheRegion = GetCacheRegion(input.MethodBase);
                string cacheKey = _cachingAttribute.CacheKey;
                if (string.IsNullOrEmpty(cacheKey)) {
                    cacheKey = CreateCacheKey(input);
                }
                IMethodReturn realReturn;
                switch (_cachingAttribute.Method) {
                    case CachingAttribute.CachingMethod.Get:
                        if (TargetMethodReturnsVoid(input)) {
                            return getNext()(input, getNext);
                        }

                        var cache = this.GetOrBuildCache(cacheRegion);

                        var cachedResult = (object[])cache.Get(cacheKey);
                        if (cachedResult == null) {
                            realReturn = getNext()(input, getNext);
                            cache.Put(cacheKey, new object[] { realReturn.ReturnValue, realReturn.Outputs });

                            return realReturn;
                        }
                        else {
                            var outputs =(cachedResult[1] as IParameterCollection).Cast<object>().ToArray();
                            IMethodReturn cachedReturn = input.CreateMethodReturn(cachedResult[0], outputs);
                            return cachedReturn;
                        }

                    case CachingAttribute.CachingMethod.Put:
                        if (TargetMethodReturnsVoid(input)) {
                            return getNext()(input, getNext);
                        }

                        IMethodReturn methodReturn = getNext().Invoke(input, getNext);
                        this.GetOrBuildCache(cacheRegion).Put(cacheKey, new object[] { methodReturn.ReturnValue, methodReturn.Outputs });

                        return methodReturn;
                    case CachingAttribute.CachingMethod.Remove:
                        foreach (var region in _cachingAttribute.RelatedAreas) {
                            this.GetOrBuildCache(region).Clear();
                        }
                        return getNext().Invoke(input, getNext);
                }

                return getNext().Invoke(input, getNext);
            }