Files
pos-system/services/iam-service-net/src/IamService.Infrastructure/DependencyInjection.cs
Ho Ngoc Hai fdcc24bdf4 feat(infrastructure): Enhance dependency injection for Redis caching and add InMemory cache service for testing
- Updated AddInfrastructure method to accept an environment name parameter for conditional Redis caching configuration.
- Implemented logic to skip Redis caching setup in the Testing environment.
- Added InMemoryCacheService for testing purposes, providing a mock implementation of ICacheService.
- Enhanced TransactionBehavior to skip transactions for InMemory databases.
- Updated functional tests to remove Redis-related services and ensure proper database setup for testing.
2026-01-12 19:04:49 +07:00

164 lines
6.8 KiB
C#

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using IamService.Domain.AggregatesModel.UserAggregate;
using IamService.Domain.AggregatesModel.RoleAggregate;
using IamService.Domain.SeedWork;
using IamService.Infrastructure.Repositories;
namespace IamService.Infrastructure;
/// <summary>
/// EN: Dependency injection extensions for Infrastructure layer.
/// VI: Dependency injection extensions cho Infrastructure layer.
/// </summary>
public static class DependencyInjection
{
/// <summary>
/// EN: Add Infrastructure services to DI container.
/// VI: Thêm Infrastructure services vào DI container.
/// </summary>
public static IServiceCollection AddInfrastructure(
this IServiceCollection services,
IConfiguration configuration,
string? environmentName = null)
{
// EN: Get database connection string
// VI: Lấy database connection string
var connectionString = configuration.GetConnectionString("DefaultConnection")
?? configuration["DATABASE_URL"]
?? throw new InvalidOperationException("Database connection string not configured");
// EN: Add DbContext with PostgreSQL
// VI: Thêm DbContext với PostgreSQL
services.AddDbContext<IamServiceContext>(options =>
{
options.UseNpgsql(connectionString, npgsqlOptions =>
{
npgsqlOptions.MigrationsAssembly(typeof(IamServiceContext).Assembly.FullName);
npgsqlOptions.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(10),
errorCodesToAdd: null);
});
// EN: Use OpenIddict EF Core stores
// VI: Sử dụng OpenIddict EF Core stores
options.UseOpenIddict();
});
// EN: Add ASP.NET Core Identity
// VI: Thêm ASP.NET Core Identity
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
// EN: Password settings
// VI: Cài đặt mật khẩu
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequiredLength = 8;
// EN: Lockout settings
// VI: Cài đặt khóa tài khoản
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// EN: User settings
// VI: Cài đặt user
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedEmail = false;
})
.AddEntityFrameworkStores<IamServiceContext>()
.AddDefaultTokenProviders();
// EN: Configure OpenIddict
// VI: Cấu hình OpenIddict
services.AddOpenIddict()
// EN: Register the OpenIddict core components
// VI: Đăng ký OpenIddict core components
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<IamServiceContext>();
})
// EN: Register the OpenIddict server components
// VI: Đăng ký OpenIddict server components
.AddServer(options =>
{
// EN: Enable token endpoints
// VI: Bật token endpoints
options.SetTokenEndpointUris("/connect/token")
.SetUserinfoEndpointUris("/connect/userinfo")
.SetIntrospectionEndpointUris("/connect/introspect")
.SetRevocationEndpointUris("/connect/revoke");
// EN: Enable flows
// VI: Bật flows
options.AllowPasswordFlow()
.AllowRefreshTokenFlow()
.AllowClientCredentialsFlow();
// EN: Register scopes
// VI: Đăng ký scopes
options.RegisterScopes("openid", "profile", "email", "roles", "api", "offline_access");
// EN: Token lifetimes
// VI: Thời hạn token
options.SetAccessTokenLifetime(TimeSpan.FromMinutes(15))
.SetRefreshTokenLifetime(TimeSpan.FromDays(7));
// EN: Development settings
// VI: Cài đặt development
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate()
.DisableAccessTokenEncryption(); // EN: Disable encryption for dev / VI: Tắt mã hóa cho dev
// EN: Accept anonymous clients (for password flow without client_id)
// VI: Chấp nhận anonymous clients (cho password flow không cần client_id)
options.AcceptAnonymousClients();
// EN: Configure ASP.NET Core integration
// VI: Cấu hình tích hợp ASP.NET Core
options.UseAspNetCore()
.EnableTokenEndpointPassthrough()
.EnableUserinfoEndpointPassthrough()
.DisableTransportSecurityRequirement(); // EN: Allow HTTP for dev / VI: Cho phép HTTP cho dev
})
// EN: Register the OpenIddict validation components
// VI: Đăng ký OpenIddict validation components
.AddValidation(options =>
{
options.UseLocalServer();
options.UseAspNetCore();
});
// EN: Register repositories
// VI: Đăng ký repositories
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IRoleRepository, RoleRepository>();
services.AddScoped<IUnitOfWork>(sp => sp.GetRequiredService<IamServiceContext>());
// EN: Configure Redis caching (skip in Testing environment)
// VI: Cấu hình Redis caching (bỏ qua trong Testing environment)
if (!string.Equals(environmentName, "Testing", StringComparison.OrdinalIgnoreCase))
{
var redisSettings = new Caching.RedisSettings();
configuration.GetSection(Caching.RedisSettings.SectionName).Bind(redisSettings);
services.AddSingleton<StackExchange.Redis.IConnectionMultiplexer>(sp =>
{
var connectionString = redisSettings.GetConnectionString();
return StackExchange.Redis.ConnectionMultiplexer.Connect(connectionString);
});
services.AddSingleton<Caching.ICacheService, Caching.RedisCacheService>();
}
return services;
}
}