コード例 #1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext <TenantDbContext>(options =>
                                                    options.UseNpgsql(Configuration.GetConnectionString("MultiTenantDb")));

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddTransient <ITenantService, TenantService>();
            services.AddScoped((serviceProvider) =>
            {
                var httpContextAccessor = serviceProvider.GetRequiredService <IHttpContextAccessor>();
                if (httpContextAccessor.HttpContext == null)
                {
                    return(null);
                }

                var userId           = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                var userTenant       = httpContextAccessor.HttpContext.User.FindFirst(CustomClaimTypes.TenantId)?.Value;
                var connectionString = Configuration.GetSection("ConnectionStrings").GetValue <string>("GamesDbTemplate")
                                       .Replace("{tenant}", userTenant);

                var tenant = new GamesTenant
                {
                    Name             = userTenant,
                    ConnectionString = connectionString,
                    Subject          = userId
                };
                return(tenant);
            });

            services.AddScoped((serviceProvider) =>
            {
                var tenant  = serviceProvider.GetRequiredService <GamesTenant>();
                var builder = new DbContextOptionsBuilder <GamesDbContext>();
                builder.UseNpgsql(tenant.ConnectionString);
                return(builder.Options);
            });

            //If Database not exists because a new tenant was registered, create this new one
            services.AddScoped(serviceProvider =>
            {
                var options = serviceProvider.GetRequiredService <DbContextOptions <GamesDbContext> >();
                var context = new GamesDbContext(options);
                var exists  = ((RelationalDatabaseCreator)context.GetService <IDatabaseCreator>()).Exists();
                if (!exists)
                {
                    context.Database.Migrate();
                }
                return(context);
            });

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                var authoriyUrl              = Configuration.GetSection("IdentityServer").GetValue <string>("Url");
                options.Authority            = authoriyUrl;
                options.Audience             = "games-api";
                options.RequireHttpsMetadata = false;     // do not do this in production!
            });

            services.AddMemoryCache();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }