/// <inheritdoc/>
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            // do not process if client-side request
            if (context.Request.IsClientSideRequest() && !_umbracoRequestOptions.Value.HandleAsServerSideRequest(context.Request))
            {
                // we need this here because for bundle requests, these are 'client side' requests that we need to handle
                LazyInitializeBackOfficeServices(context.Request.Path);
                await next(context);

                return;
            }

            // Profiling start needs to be one of the first things that happens.
            // Also MiniProfiler.Current becomes null if it is handled by the event aggregator due to async/await
            _profiler?.UmbracoApplicationBeginRequest(context, _runtimeState.Level);

            _variationContextAccessor.VariationContext ??= new VariationContext(_defaultCultureAccessor.DefaultCulture);
            UmbracoContextReference umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext();

            Uri?currentApplicationUrl = GetApplicationUrlFromCurrentRequest(context.Request);

            _hostingEnvironment.EnsureApplicationMainUrl(currentApplicationUrl);

            var pathAndQuery = context.Request.GetEncodedPathAndQuery();

            try
            {
                // Verbose log start of every request
                LogHttpRequest.TryGetCurrentHttpRequestId(out Guid? httpRequestId, _requestCache);
                _logger.LogTrace("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, pathAndQuery);

                try
                {
                    LazyInitializeBackOfficeServices(context.Request.Path);
                    await _eventAggregator.PublishAsync(new UmbracoRequestBeginNotification(umbracoContextReference.UmbracoContext));
                }
                catch (Exception ex)
                {
                    // try catch so we don't kill everything in all requests
                    _logger.LogError(ex.Message);
                }
                finally
                {
                    try
                    {
                        await next(context);
                    }
                    finally
                    {
                        await _eventAggregator.PublishAsync(new UmbracoRequestEndNotification(umbracoContextReference.UmbracoContext));
                    }
                }
            }
            finally
            {
                // Verbose log end of every request (in v8 we didn't log the end request of ALL requests, only the front-end which was
                // strange since we always logged the beginning, so now we just log start/end of all requests)
                LogHttpRequest.TryGetCurrentHttpRequestId(out Guid? httpRequestId, _requestCache);
                _logger.LogTrace("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, pathAndQuery, DateTime.Now.Subtract(umbracoContextReference.UmbracoContext.ObjectCreated).TotalMilliseconds);

                try
                {
                    DisposeHttpContextItems(context.Request);
                }
                finally
                {
                    // Dispose the umbraco context reference which will in turn dispose the UmbracoContext itself.
                    umbracoContextReference.Dispose();
                }
            }

            // Profiling end needs to be last of the first things that happens.
            // Also MiniProfiler.Current becomes null if it is handled by the event aggregator due to async/await
            _profiler?.UmbracoApplicationEndRequest(context, _runtimeState.Level);
        }