Example #1
0
        // 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);
            }
        }
Example #5
0
        /// <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);
                }
            }
        }