Init Git
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
using AMREZ.EOP.Abstractions.Applications.Tenancy;
|
||||
using AMREZ.EOP.Abstractions.Applications.UseCases.Authentications;
|
||||
using AMREZ.EOP.Abstractions.Applications.UseCases.HumanResources;
|
||||
using AMREZ.EOP.Abstractions.Applications.UseCases.Tenancy;
|
||||
using AMREZ.EOP.Abstractions.Infrastructures.Common;
|
||||
using AMREZ.EOP.Abstractions.Infrastructures.Repositories;
|
||||
using AMREZ.EOP.Abstractions.Security;
|
||||
using AMREZ.EOP.Abstractions.Storage;
|
||||
using AMREZ.EOP.Application.UseCases.Authentications;
|
||||
using AMREZ.EOP.Application.UseCases.HumanResources;
|
||||
using AMREZ.EOP.Application.UseCases.Tenancy;
|
||||
using AMREZ.EOP.Domain.Shared.Tenancy;
|
||||
using AMREZ.EOP.Infrastructures.Data;
|
||||
using AMREZ.EOP.Infrastructures.Options;
|
||||
using AMREZ.EOP.Infrastructures.Repositories;
|
||||
using AMREZ.EOP.Infrastructures.Security;
|
||||
using AMREZ.EOP.Infrastructures.Storage;
|
||||
using AMREZ.EOP.Infrastructures.Tenancy;
|
||||
using AMREZ.EOP.Infrastructures.UnitOfWork;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace AMREZ.EOP.Infrastructures.DependencyInjections;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
|
||||
{
|
||||
services.AddHttpContextAccessor();
|
||||
|
||||
// Options
|
||||
services.AddOptions<AuthOptions>()
|
||||
.BindConfiguration("Connections")
|
||||
.ValidateOnStart();
|
||||
|
||||
// Tenancy core (order matters for AddDbContext factory resolution)
|
||||
services.AddSingleton(sp =>
|
||||
{
|
||||
var map = new TenantMap();
|
||||
var opts = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
|
||||
map.UpsertTenant("public", new TenantContext
|
||||
{
|
||||
Id = "public",
|
||||
Schema = "public",
|
||||
ConnectionString = string.IsNullOrWhiteSpace(opts.DefaultConnection) ? null : opts.DefaultConnection,
|
||||
Mode = TenantMode.Rls
|
||||
});
|
||||
return map;
|
||||
});
|
||||
services.AddHostedService<TenantMapLoader>();
|
||||
services.AddScoped<SearchPathInterceptor>();
|
||||
services.AddScoped<TenantRlsInterceptor>();
|
||||
services.AddScoped<ITenantResolver, DefaultTenantResolver>();
|
||||
services.AddScoped<ITenantDbContextFactory, TenantDbContextFactory>();
|
||||
services.AddScoped<ITenantProvisioner, TenantProvisioner>();
|
||||
|
||||
// DbContext (attach RLS/search_path interceptors)
|
||||
services.AddDbContext<AppDbContext>((sp, o) =>
|
||||
{
|
||||
var cfg = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
|
||||
o.UseNpgsql(cfg.DefaultConnection);
|
||||
o.AddInterceptors(
|
||||
sp.GetRequiredService<SearchPathInterceptor>(),
|
||||
sp.GetRequiredService<TenantRlsInterceptor>()
|
||||
);
|
||||
});
|
||||
|
||||
// Db scope / UoW
|
||||
services.AddScoped<IDbScope, DbScope>();
|
||||
services.AddScoped<EFUnitOfWork>();
|
||||
services.AddScoped<IUnitOfWork, EFUnitOfWork>();
|
||||
|
||||
// Security
|
||||
services.AddScoped<IPasswordHasher, BcryptPasswordHasher>();
|
||||
|
||||
// Repositories — Auth & HR แยกกัน
|
||||
services.AddScoped<IUserRepository, UserRepository>();
|
||||
services.AddScoped<IUserProfileRepository, UserProfileRepository>();
|
||||
services.AddScoped<ITenantRepository, TenantRepository>();
|
||||
|
||||
// UseCases — Authentication
|
||||
services.AddScoped<ILoginUseCase, LoginUseCase>();
|
||||
services.AddScoped<IRegisterUseCase, RegisterUseCase>();
|
||||
services.AddScoped<IChangePasswordUseCase, ChangePasswordUseCase>();
|
||||
services.AddScoped<IAddEmailIdentityUseCase, AddEmailIdentityUseCase>();
|
||||
services.AddScoped<IVerifyEmailUseCase, VerifyEmailUseCase>();
|
||||
services.AddScoped<IEnableTotpUseCase, EnableTotpUseCase>();
|
||||
services.AddScoped<IDisableMfaUseCase, DisableMfaUseCase>();
|
||||
services.AddScoped<ILogoutUseCase, LogoutUseCase>();
|
||||
services.AddScoped<ILogoutAllUseCase, LogoutAllUseCase>();
|
||||
|
||||
// UseCases — HR
|
||||
services.AddScoped<IUpsertUserProfileUseCase, UpsertUserProfileUseCase>();
|
||||
services.AddScoped<IAddEmploymentUseCase, AddEmploymentUseCase>();
|
||||
services.AddScoped<IEndEmploymentUseCase, EndEmploymentUseCase>();
|
||||
services.AddScoped<IAddEmployeeAddressUseCase, AddEmployeeAddressUseCase>();
|
||||
services.AddScoped<ISetPrimaryAddressUseCase, SetPrimaryAddressUseCase>();
|
||||
services.AddScoped<IAddEmergencyContactUseCase, AddEmergencyContactUseCase>();
|
||||
services.AddScoped<ISetPrimaryEmergencyContactUseCase, SetPrimaryEmergencyContactUseCase>();
|
||||
services.AddScoped<IAddEmployeeBankAccountUseCase, AddEmployeeBankAccountUseCase>();
|
||||
services.AddScoped<ISetPrimaryBankAccountUseCase, SetPrimaryBankAccountUseCase>();
|
||||
|
||||
// UseCases — Tenancy
|
||||
services.AddScoped<ICreateTenantUseCase, CreateTenantUseCase>();
|
||||
services.AddScoped<IUpdateTenantUseCase, UpdateTenantUseCase>();
|
||||
services.AddScoped<IDeleteTenantUseCase, DeleteTenantUseCase>();
|
||||
services.AddScoped<IMapDomainUseCase, MapDomainUseCase>();
|
||||
services.AddScoped<IUnmapDomainUseCase, UnmapDomainUseCase>();
|
||||
services.AddScoped<IAddBaseDomainUseCase, AddBaseDomainUseCase>();
|
||||
services.AddScoped<IRemoveBaseDomainUseCase, RemoveBaseDomainUseCase>();
|
||||
services.AddScoped<IListTenantsUseCase, ListTenantsUseCase>();
|
||||
services.AddScoped<IListDomainsUseCase, ListDomainsUseCase>();
|
||||
|
||||
// Redis (optional)
|
||||
services.AddSingleton<IConnectionMultiplexer?>(sp =>
|
||||
{
|
||||
var opts = sp.GetRequiredService<IOptions<AuthOptions>>().Value;
|
||||
var conn = opts.RedisConnection;
|
||||
if (string.IsNullOrWhiteSpace(conn)) return null;
|
||||
|
||||
try
|
||||
{
|
||||
var cfg = ConfigurationOptions.Parse(conn, true);
|
||||
cfg.AbortOnConnectFail = false;
|
||||
cfg.ConnectTimeout = 1000;
|
||||
cfg.SyncTimeout = 1000;
|
||||
var mux = ConnectionMultiplexer.Connect(cfg);
|
||||
return mux.IsConnected ? mux : null;
|
||||
}
|
||||
catch { return null; }
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user