// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app.Use(async(context, next) => { Guid correlationId = Guid.NewGuid(); Console.WriteLine($"Register feature with correlation id: {correlationId}"); IFeatureCollection features = context.Features; features.Set <CorrelationFeature>(new CorrelationFeature(correlationId)); await next(); }); app.Use(async(context, next) => { IFeatureCollection features = context.Features; CorrelationFeature correlatinFeature = features.Get <CorrelationFeature>(); Console.WriteLine($"CorrelationId: {correlatinFeature.Id}"); IServiceProvidersFeature serviceProviderFeature = features.Get <IServiceProvidersFeature>(); IServiceProvider service = serviceProviderFeature.RequestServices; await next(); }); app.UseMvc(); }
void IFeatureCache.CheckFeaturesRevision() { if (_cachedFeaturesRevision !=_features.Revision) { _items = null; _serviceProviders = null; _authentication = null; _lifetime = null; _session = null; _cachedFeaturesRevision = _features.Revision; } }
void IFeatureCache.CheckFeaturesRevision() { if (_cachedFeaturesRevision != _features.Revision) { _items = null; _serviceProviders = null; _authentication = null; _lifetime = null; _session = null; _cachedFeaturesRevision = _features.Revision; } }
/// <summary> /// Invokes the middleware using the specified context. /// </summary> /// <param name="context"> /// The request context to process through the middleware. /// </param> /// <returns> /// A <see cref="Task"/> to await for completion of the operation. /// </returns> public async Task Invoke(HttpContext context) { // If there isn't already an HttpContext set on the context // accessor for this async/thread operation, set it. This allows // tenant identification to use it. if (this._contextAccessor.HttpContext == null) { this._contextAccessor.HttpContext = context; } var container = this._multitenantContainerAccessor(); if (container == null) { throw new InvalidOperationException(Properties.Resources.NoMultitenantContainerAvailable); } IServiceProvidersFeature existingFeature = null; try { var autofacFeature = RequestServicesFeatureFactory.CreateFeature(context, container.Resolve <IServiceScopeFactory>()); var disp = autofacFeature as IDisposable; if (disp != null) { context.Response.RegisterForDispose(disp); } existingFeature = context.Features.Get <IServiceProvidersFeature>(); context.Features.Set(autofacFeature); await this._next.Invoke(context); } finally { // In ASP.NET Core 1.x the existing feature will disposed as part of // a using statement; in ASP.NET Core 2.x it is registered directly // with the response for disposal. In either case, we don't have to // do that. We do put back any existing feature, though, since // at this point there may have been some default tenant or base // container level stuff resolved and after this middleware it needs // to be what it was before. context.Features.Set(existingFeature); } }
/// <summary> /// Invokes the middleware using the specified context. /// </summary> /// <param name="httpContext"> /// The request context to process through the middleware. /// </param> /// <returns> /// A <see cref="Task"/> to await for completion of the operation. /// </returns> public async Task Invoke(HttpContext httpContext) { Debug.Assert(httpContext != null, nameof(httpContext)); TenantContext <TTenant> tenantContext = httpContext.GetTenantContext <TTenant>(); if (tenantContext != null) { IServiceProvidersFeature existingRequestServices = httpContext.Features.Get <IServiceProvidersFeature>(); using (RequestServicesFeature feature = new RequestServicesFeature(httpContext, serviceFactoryForMultitenancy.Build(tenantContext).GetRequiredService <IServiceScopeFactory>())) { // Replace the request IServiceProvider created by IServiceScopeFactory httpContext.RequestServices = feature.RequestServices; ILog <MultitenancyRequestServicesContainerMiddleware <TTenant> > log = httpContext.RequestServices.GetRequiredService <ILog <MultitenancyRequestServicesContainerMiddleware <TTenant> > >(); log.Log(Logging.LibLog.LogLevel.Info, () => $"IServiceProvider is successfully set for tenant {tenantContext.Id}"); await next.Invoke(httpContext).ConfigureAwait(false); } } }