public async Task Invoke(HttpContext context,
                                 RequestServicesSwapper <TTenant> requestServicesSwapper,
                                 ITenantContainerAccessor <TTenant> tenantContainerAccessor,
                                 ITenantRequestContainerAccessor <TTenant> requestContainerAccessor)
        {
            _logger.LogDebug("Tenant Container Middleware - Start.");

            var tenantContainer = await tenantContainerAccessor.TenantContainer.Value;

            if (tenantContainer == null)
            {
                _logger.LogDebug("Tenant Container Middleware - No tenant container.");
                await _next.Invoke(context);

                return;
            }

            var oldAppBuilderServices = _appBuilder.ApplicationServices;

            try
            {
                // Can't remember why this is necessary to swap appBuilder.ApplicationServices here.. might be some mvc thing, need to rediscover.
                _logger.LogDebug("Setting AppBuilder Services to Tenant Container: {containerId} - {containerName}", tenantContainer.ContainerId, tenantContainer.ContainerName);
                _appBuilder.ApplicationServices = tenantContainer;
                var perRequestContainer = await requestContainerAccessor.TenantRequestContainer.Value;

                // Ensure per request container is disposed at end of request.
                context.Response.RegisterForDispose(perRequestContainer);

                // Replace request services with a nested version (for lifetime management - used to encpasulate a request).
                _logger.LogDebug("Setting Request Container: {containerId} - {containerName}", perRequestContainer.ContainerId, perRequestContainer.ContainerName);

                requestServicesSwapper.SwapRequestServices(perRequestContainer);
                //  var swapContextRequestServices = new RequestServicesSwapper(perRequestContainer);
                // swapContextRequestServices.SwapRequestServices()
                await _next?.Invoke(context);

                //await swapContextRequestServices.ExecuteWithinSwappedRequestContainer(_next, context);
                _logger.LogDebug("Restoring Request Container");
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex.Message);
            }
            finally
            {
                _logger.LogDebug("Restoring AppBuilder Services");
                _appBuilder.ApplicationServices = oldAppBuilderServices;
            }
        }
        public async Task Invoke(HttpContext context, ITenantContainerAccessor <TTenant> tenantContainerAccessor)
        {
            // need to ensure all modules are initialised.
            await _moduleManager.EnsureStarted(() =>
            {
                return(tenantContainerAccessor.TenantContainer.Value);
            }, _rootApp);

            var router       = _moduleManager.GetModulesRouter();
            var routeContext = new ModulesRouteContext <TModule>(context);

            routeContext.RouteData.Routers.Add(router);

            await router.RouteAsync(routeContext);

            if (routeContext.Handler == null)
            {
                _logger.LogDebug("Request did not match routes for any modules..");
                await _next.Invoke(context);

                return;
            }

            var routedModule = routeContext.ModuleShell;

            routeContext.HttpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature()
            {
                RouteData = routeContext.RouteData,
            };

            var moduleName = routedModule.Module.GetType().Name;

            _logger.LogDebug("Request matched module {0}", moduleName);

            // Replace request services with a nested version of the routed modules container.
            using (var scope = routedModule.Container.CreateNestedContainer($"ModulesMiddleware:{moduleName}"))
            {
                _logger.LogDebug("Setting Request: {containerId} - {containerName}", scope.ContainerId, scope.ContainerName);
                var oldRequestServices = context.RequestServices;
                context.RequestServices = scope;
                await routeContext.Handler(routeContext.HttpContext);

                _logger.LogDebug("Restoring Request Container");
                context.RequestServices = oldRequestServices;
            }
        }
        public TenantRequestContainerAccessor(
            ILogger <TenantRequestContainerAccessor <TTenant> > logger,
            ITenantContainerAccessor <TTenant> tenantContainerAccessor)
        {
            _logger = logger;
            _tenantContainerAccessor = tenantContainerAccessor;

            TenantRequestContainer = new Lazy <Task <PerRequestContainer> >(async() =>
            {
                var tenantContainer = await tenantContainerAccessor.TenantContainer.Value;
                if (tenantContainer == null)
                {
                    return(null);
                }

                var requestContainer = tenantContainer.CreateNestedContainer(true);
                return(new PerRequestContainer(requestContainer));
            });
        }
        public TenantRequestContainerAccessor(
            ILogger <TenantRequestContainerAccessor <TTenant> > logger,
            ITenantContainerAccessor <TTenant> tenantContainerAccessor,
            ITenantContainerEventsPublisher <TTenant> containerEventsPublisher)
        {
            _containerEventsPublisher = containerEventsPublisher;

            TenantRequestContainer = new Lazy <Task <ITenantContainerAdaptor> >(async() =>
            {
                var tenantContainer = await tenantContainerAccessor.TenantContainer.Value;
                if (tenantContainer == null)
                {
                    return(null);
                }

                var requestContainer = tenantContainer.CreateNestedContainer($"{tenantContainer.ContainerName}");
                logger.LogDebug("Creating container name: {ContainerName}", tenantContainer.ContainerName);

                _containerEventsPublisher?.PublishNestedTenantContainerCreated(requestContainer);
                return(requestContainer);
            });
        }
Пример #5
0
        public async Task Invoke(HttpContext context, ITenantContainerAccessor <TTenant> tenantContainerAccessor, ITenantRequestContainerAccessor <TTenant> requestContainerAccessor)
        {
            _logger.LogDebug("Tenant Container Middleware - Start.");

            var tenantContainer = await tenantContainerAccessor.TenantContainer.Value;

            if (tenantContainer == null)
            {
                _logger.LogDebug("Tenant Container Middleware - No tenant container.");
                await _next.Invoke(context);

                return;
            }

            var oldAppBuilderServices = _appBuilder.ApplicationServices;

            try
            {
                _logger.LogDebug("Setting AppBuilder Services to Tenant Container: {containerId} - {containerName}", tenantContainer.ContainerId, tenantContainer.ContainerName);
                _appBuilder.ApplicationServices = tenantContainer;
                var perRequestContainer = await requestContainerAccessor.TenantRequestContainer.Value;

                // Ensure container is disposed at end of request.
                context.Response.RegisterForDispose(perRequestContainer);

                // Replace request services with a nested version (for lifetime management - used to encpasulate a request).
                _logger.LogDebug("Setting Request Container: {containerId} - {containerName}", perRequestContainer.RequestContainer.ContainerId, perRequestContainer.RequestContainer.ContainerName);
                await perRequestContainer.ExecuteWithinSwappedRequestContainer(_next, context);

                _logger.LogDebug("Restoring Request Container");
            }
            finally
            {
                _logger.LogDebug("Restoring AppBuilder Services");
                _appBuilder.ApplicationServices = oldAppBuilderServices;
            }
        }
        public async Task Invoke(HttpContext context, ITenantNancyBootstrapperAccessor <TTenant> tenantNancyBootstrapper, ITenantContainerAccessor <TTenant> tenantContainerAccessor, ITenantRequestContainerAccessor <TTenant> tenantRequestContainerAccessor)
        {
            // get the nancy bootstrapper,
            // adjust its request container - give it the current request container to return.
            // get the nancy engine

            //  var tenantContainer = await tenantContainerAccessor.TenantContainer.Value;
            var tenantRequestContainer = await tenantRequestContainerAccessor.TenantRequestContainer.Value;
            var nancyBootstrapper      = await tenantNancyBootstrapper.Bootstrapper.Value;

            if (tenantRequestContainer == null || nancyBootstrapper == null)
            {
                await _next.Invoke(context);

                return;
            }

            // swap out nancy request services.
            ITenantContainerAdaptor old = nancyBootstrapper.RequestContainerAdaptor;

            try
            {
                nancyBootstrapper.RequestContainerAdaptor = tenantRequestContainer.RequestContainer;
                var engine       = nancyBootstrapper.GetEngine();
                var nancyHandler = new NancyHandler(engine);
                await nancyHandler.ProcessRequest(context, NancyPassThroughOptions.PassThroughWhenStatusCodesAre(global::Nancy.HttpStatusCode.NotFound), _next);
            }
            finally
            {
                nancyBootstrapper.RequestContainerAdaptor = old;
            }
        }
 public TenantNancyBootstrapperFactory(ITenantContainerAccessor <TTenant> tenantContainerAccessor)
 {
     _tenantContainerAccessor = tenantContainerAccessor;
 }