public async Task Invoke(HttpContext context)
        {
            var requestFeatures = context.Features.Get <IHttpRequestFeature>();

            if (!_settings.Enabled || !HttpMethods.IsGet(requestFeatures.Method) || (context.Request.GetTypedHeaders().CacheControl?.NoCache ?? false))
            {
                await _next.Invoke(context);

                return;
            }

            var cacheKey = requestFeatures.RawTarget;

            try
            {
                CachedResponse cachedResponse = null;
                if (context.User.Identity.IsAuthenticated)
                {
                    cachedResponse = _memoryCache.Get <CachedResponse>($"{cacheKey}_u:{context.User.FindFirst(ClaimTypes.NameIdentifier).Value}");
                    if (cachedResponse == null)
                    {
                        cachedResponse = _memoryCache.Get <CachedResponse>(cacheKey);

                        if (cachedResponse?.ForAnonymusUsers ?? false)
                        {
                            cachedResponse = null;
                        }
                    }
                }
                else
                {
                    cachedResponse = _memoryCache.Get <CachedResponse>(cacheKey);
                }

                if (cachedResponse != null)
                {
                    await cachedResponse.Apply(context).ConfigureAwait(false);

                    return;
                }
            }
            catch (Exception ex) {
                _logger.Exception(ex);
            }

            var cachedItem = await CaptureResponse(context).ConfigureAwait(false);

            if (cachedItem != null)
            {
                try
                {
                    if (context.Items.TryGetValue(Consts.IsCachebleKey, out object isCacheble) && (isCacheble is bool) && (bool)isCacheble)
                    {
                        cacheKey = requestFeatures.RawTarget;
                        if (context.Items.TryGetValue(Consts.IsUserSpecificKey, out object isUserSpecific) &&
                            (isUserSpecific is bool) && (bool)isUserSpecific)
                        {
                            if (context.User.Identity.IsAuthenticated)
                            {
                                cacheKey = $"{cacheKey}_u:{context.User.FindFirst(ClaimTypes.NameIdentifier).Value}";
                            }
                            else
                            {
                                cachedItem.ForAnonymusUsers = true;
                            }
                        }

                        var slidingDuration = (context.Items.TryGetValue(Consts.SlidingDurationKey, out object slidingDurationO) && (slidingDurationO is int)) ?
                                              TimeSpan.FromSeconds((int)slidingDurationO) : TimeSpan.Zero;

                        var duration = (context.Items.TryGetValue(Consts.DurationKey, out object durationO) && (durationO is int)) ?
                                       TimeSpan.FromSeconds((int)durationO) :
                                       TimeSpan.FromSeconds(_settings.MaxCacheInSec);

                        var options = new MemoryCacheEntryOptions();
                        if (slidingDuration > TimeSpan.Zero)
                        {
                            options.SlidingExpiration = slidingDuration;
                        }
                        else
                        {
                            options.AbsoluteExpirationRelativeToNow = duration;
                        }

                        Dictionary <string, string> tagsToApply = null;
                        if (context.Items.TryGetValue(Consts.CachedObjectTags, out var tagsO) && tagsO is Dictionary <string, string> tags)
                        {
                            tagsToApply = tags;
                        }

                        _memoryCache.Add(cacheKey, cachedItem, options, tagsToApply);
                    }
                }
                catch (Exception ex)
                {
                    _logger.Exception(ex);
                }
            }
        }