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); }); }
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; }