Files
tiku-backend.net/Tiku.Infrastructure/DependencyInjection.cs
xiong c497a3ca8d
Some checks failed
ci / release-gate (push) Has been cancelled
清理代码
2026-08-03 12:31:39 +08:00

92 lines
4.2 KiB
C#

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Npgsql;
using StackExchange.Redis;
using Tiku.Application.Security;
using Tiku.Domain.Identity;
using Tiku.Infrastructure.Auth;
using Tiku.Infrastructure.Observability;
using Tiku.Infrastructure.Persistence;
using Tiku.Infrastructure.Security;
namespace Tiku.Infrastructure;
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(
this IServiceCollection services,
string connectionString,
Action<DbContextOptionsBuilder>? configureDatabase = null)
{
ArgumentException.ThrowIfNullOrWhiteSpace(connectionString);
services.AddSingleton(_ => NpgsqlDataSource.Create(connectionString));
services.AddScoped<TenantIsolationSaveChangesInterceptor>();
services.AddSingleton<DatabasePerformanceInterceptor>();
services.AddDbContext<TikuDbContext>((serviceProvider, options) =>
{
var dataSource = serviceProvider.GetRequiredService<NpgsqlDataSource>();
options.UseNpgsql(dataSource, npgsql =>
npgsql.MigrationsAssembly(typeof(TikuDbContext).Assembly.FullName));
configureDatabase?.Invoke(options);
options.AddInterceptors(
serviceProvider.GetRequiredService<TenantIsolationSaveChangesInterceptor>(),
serviceProvider.GetRequiredService<DatabasePerformanceInterceptor>());
});
services.AddIdentityCore<User>(options =>
{
options.Password.RequiredLength = 8;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.User.RequireUniqueEmail = false;
})
.AddEntityFrameworkStores<TikuDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders()
.AddPasswordValidator<LetterAndDigitPasswordValidator<User>>();
services.Configure<PasswordHasherOptions>(options => options.IterationCount = 210_000);
services.AddPlatformCoreModule();
services.AddAuthModule();
services.AddContentModule();
services.AddLearningModule();
services.AddTenantAdminModule();
services.AddCommerceModule();
services.AddJobsModule();
services.AddPlatformModule();
return services;
}
public static IServiceCollection AddRedisSecurity(
this IServiceCollection services,
string connectionString,
string environmentName)
{
ArgumentException.ThrowIfNullOrWhiteSpace(connectionString);
var options = ConfigurationOptions.Parse(connectionString);
options.AbortOnConnectFail = false;
options.ClientName = $"tiku-{environmentName.ToLowerInvariant()}";
services.AddSingleton<IConnectionMultiplexer>(_ => ConnectionMultiplexer.Connect(options));
services.AddSingleton(provider => new RedisSecurityStore(
provider.GetRequiredService<IConnectionMultiplexer>(),
environmentName,
provider.GetRequiredService<ILogger<RedisSecurityStore>>()));
services.AddSingleton<IRedisSecurityStore>(provider => provider.GetRequiredService<RedisSecurityStore>());
services.AddSingleton(provider => new RedisAuthorizationCache(
provider.GetRequiredService<IConnectionMultiplexer>(),
provider.GetRequiredService<IOptions<AuthorizationCacheOptions>>(),
environmentName));
services.AddSingleton<IAccessSecurityCache>(provider => provider.GetRequiredService<RedisAuthorizationCache>());
services.AddSingleton<IAuthorizationSnapshotCache>(provider =>
provider.GetRequiredService<RedisAuthorizationCache>());
services.AddStackExchangeRedisCache(cache => cache.ConfigurationOptions = options);
return services;
}
}