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, 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 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 CanResolveTOptionsFromTenantRequestContainer() { ILogger <AutofacOptionsTests> logger = _loggerFactory.CreateLogger <AutofacOptionsTests>(); IServiceCollection services = new ServiceCollection() as IServiceCollection; services.AddLogging(); IServiceProvider serviceProvider = services.AddMultiTenancy <Tenant>((options) => { options .IdentifyTenantTask(() => Task.FromResult(new TenantIdentifier(new Uri("unittest://")))) .AddAspNetCore() .InitialiseTenant(tenantId => { if (tenantId.Uri.Scheme != "unittest") { throw new ArgumentException(); } return(new TenantShell <Tenant>(new Tenant())); }) .ConfigureTenantContainers((containerBuilder) => { containerBuilder.Events((events) => { // callback invoked after tenant container is created. events.OnTenantContainerCreated(async(tenantResolver, tenantServiceProvider) => { Tenant tenant = await tenantResolver; }) // callback invoked after a nested container is created for a tenant. i.e typically during a request. .OnNestedTenantContainerCreated(async(tenantResolver, tenantServiceProvider) => { Tenant tenant = await tenantResolver; }); }) // Extension methods available here for supported containers. We are using structuremap.. // We are using an overload that allows us to configure structuremap with familiar IServiceCollection. .Autofac((tenant, tenantServices) => { tenantServices.AddOptions(); tenantServices.Configure <MyOptions>((a) => { a.Foo = true; }); }); }); }); IServiceScopeFactory scopeFactory = serviceProvider.GetRequiredService <IServiceScopeFactory>(); IServiceScope scoped = scopeFactory.CreateScope(); ITenantRequestContainerAccessor <Tenant> tenantRequestContainerAccessor = scoped.ServiceProvider.GetRequiredService <ITenantRequestContainerAccessor <Tenant> >(); var requestContainer = await tenantRequestContainerAccessor.TenantRequestContainer.Value; IOptions <MyOptions> registeredoptions = requestContainer.GetRequiredService <IOptions <MyOptions> >(); var myOptions = registeredoptions.Value; Assert.True(myOptions.Foo); }