|
|
|
|
using CellularManagement.Infrastructure.Context;
|
|
|
|
|
using CellularManagement.Infrastructure.Options;
|
|
|
|
|
using CellularManagement.Infrastructure.Repositories;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using CellularManagement.Domain.Entities;
|
|
|
|
|
using CellularManagement.Domain.Repositories;
|
|
|
|
|
using CellularManagement.Infrastructure.Services;
|
|
|
|
|
using Scrutor;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using CellularManagement.Infrastructure.Configurations;
|
|
|
|
|
using CellularManagement.Domain.Services;
|
|
|
|
|
using CellularManagement.Domain.Options;
|
|
|
|
|
using CellularManagement.Infrastructure.Repositories.CQRS;
|
|
|
|
|
using CellularManagement.Infrastructure.Repositories.Identity;
|
|
|
|
|
using CellularManagement.Infrastructure.Configurations.Common;
|
|
|
|
|
using CellularManagement.Domain.Repositories.Base;
|
|
|
|
|
using CellularManagement.Domain.Repositories.Identity;
|
|
|
|
|
using CellularManagement.Infrastructure.Services.Authentication;
|
|
|
|
|
using CellularManagement.Infrastructure.Services.Infrastructure;
|
|
|
|
|
using CellularManagement.Infrastructure.Services.Security;
|
|
|
|
|
using CellularManagement.Infrastructure.Services.UserManagement;
|
|
|
|
|
using CellularManagement.Domain.Repositories.Device;
|
|
|
|
|
using CellularManagement.Domain.Repositories.NetworkProfile;
|
|
|
|
|
using CellularManagement.Infrastructure.Repositories.Device;
|
|
|
|
|
using CellularManagement.Infrastructure.Repositories.NetworkProfile;
|
|
|
|
|
|
|
|
|
|
namespace CellularManagement.Infrastructure;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 依赖注入扩展方法
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class DependencyInjection
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加基础设施服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="services">服务集合</param>
|
|
|
|
|
/// <param name="configuration">配置</param>
|
|
|
|
|
/// <returns>服务集合</returns>
|
|
|
|
|
public static IServiceCollection AddInfrastructure(
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
ArgumentNullException.ThrowIfNull(services);
|
|
|
|
|
ArgumentNullException.ThrowIfNull(configuration);
|
|
|
|
|
|
|
|
|
|
// 注册配置验证器
|
|
|
|
|
services.AddSingleton<ConfigurationValidator>();
|
|
|
|
|
|
|
|
|
|
// 验证配置
|
|
|
|
|
var validator = services.BuildServiceProvider().GetRequiredService<ConfigurationValidator>();
|
|
|
|
|
validator.ValidateDatabaseConfiguration();
|
|
|
|
|
validator.ValidateJwtConfiguration();
|
|
|
|
|
validator.ValidateEmailConfiguration();
|
|
|
|
|
|
|
|
|
|
services
|
|
|
|
|
.AddDatabaseServices(configuration)
|
|
|
|
|
.AddJwtServices(configuration)
|
|
|
|
|
.AddEmailServices(configuration)
|
|
|
|
|
.AddCacheServices()
|
|
|
|
|
.AddRepositoryServices()
|
|
|
|
|
.AddIdentityServices()
|
|
|
|
|
.AddAutoRegisteredServices();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加数据库服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddDatabaseServices(
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
var databaseOptions = configuration
|
|
|
|
|
.GetSection(DatabaseOptions.SectionName)
|
|
|
|
|
.Get<DatabaseOptions>();
|
|
|
|
|
|
|
|
|
|
if (databaseOptions is null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException(
|
|
|
|
|
nameof(databaseOptions),
|
|
|
|
|
"Database options not configured");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置数据库选项
|
|
|
|
|
services.Configure<DatabaseOptions>(configuration.GetSection(DatabaseOptions.SectionName));
|
|
|
|
|
|
|
|
|
|
if (databaseOptions.DefaultConnection is null)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentNullException(
|
|
|
|
|
nameof(databaseOptions.DefaultConnection),
|
|
|
|
|
"Database connection string not configured");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置数据库上下文
|
|
|
|
|
services.AddDbContext<AppDbContext>(options =>
|
|
|
|
|
{
|
|
|
|
|
// 使用 PostgreSQL 数据库
|
|
|
|
|
options.UseNpgsql(
|
|
|
|
|
databaseOptions.DefaultConnection,
|
|
|
|
|
sqlOptions =>
|
|
|
|
|
{
|
|
|
|
|
// 配置重试策略
|
|
|
|
|
sqlOptions.EnableRetryOnFailure(3);
|
|
|
|
|
// 配置命令超时时间
|
|
|
|
|
sqlOptions.CommandTimeout(databaseOptions.CommandTimeout);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 配置详细错误信息
|
|
|
|
|
if (databaseOptions.EnableDetailedErrors)
|
|
|
|
|
{
|
|
|
|
|
options.EnableDetailedErrors();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置敏感数据日志记录
|
|
|
|
|
if (databaseOptions.EnableSensitiveDataLogging)
|
|
|
|
|
{
|
|
|
|
|
options.EnableSensitiveDataLogging();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 注册工作单元
|
|
|
|
|
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加邮件服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddEmailServices(
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
services.Configure<EmailOptions>(configuration.GetSection(EmailOptions.SectionName));
|
|
|
|
|
services.Configure<EmailVerificationOptions>(configuration.GetSection(EmailVerificationOptions.SectionName));
|
|
|
|
|
services.AddScoped<IEmailService, EmailService>();
|
|
|
|
|
services.AddScoped<IEmailVerificationService, EmailVerificationService>();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加缓存服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddCacheServices(this IServiceCollection services)
|
|
|
|
|
{
|
|
|
|
|
services.AddMemoryCache();
|
|
|
|
|
services.AddDistributedMemoryCache();
|
|
|
|
|
services.AddScoped<ICacheService, CacheService>();
|
|
|
|
|
services.AddScoped<ICaptchaService, CaptchaService>();
|
|
|
|
|
services.AddScoped<ICaptchaVerificationService, CaptchaVerificationService>();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加仓储服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddRepositoryServices(this IServiceCollection services)
|
|
|
|
|
{
|
|
|
|
|
// 注册通用仓储
|
|
|
|
|
services.AddScoped(typeof(ICommandRepository<>), typeof(CommandRepository<>));
|
|
|
|
|
services.AddScoped(typeof(IQueryRepository<>), typeof(QueryRepository<>));
|
|
|
|
|
|
|
|
|
|
// 注册特定仓储
|
|
|
|
|
services.AddScoped<IPermissionRepository, PermissionRepository>();
|
|
|
|
|
services.AddScoped<ILoginLogRepository, LoginLogRepository>();
|
|
|
|
|
services.AddScoped<IUserRoleRepository, UserRoleRepository>();
|
|
|
|
|
|
|
|
|
|
// 注册设备相关仓储
|
|
|
|
|
services.AddScoped<ICellularDeviceRepository, CellularDeviceRepository>();
|
|
|
|
|
services.AddScoped<IProtocolVersionRepository, ProtocolVersionRepository>();
|
|
|
|
|
services.AddScoped<ICellularDeviceRuntimeRepository, CellularDeviceRuntimeRepository>();
|
|
|
|
|
services.AddScoped<IRAN_ConfigurationRepository, RAN_ConfigurationRepository>();
|
|
|
|
|
services.AddScoped<ICoreNetworkConfigRepository, CoreNetworkConfigRepository>();
|
|
|
|
|
services.AddScoped<IIMS_ConfigurationRepository, IMS_ConfigurationRepository>();
|
|
|
|
|
services.AddScoped<INetworkStackConfigRepository, NetworkStackConfigRepository>();
|
|
|
|
|
services.AddScoped<IStack_CoreIMS_BindingRepository, Stack_CoreIMS_BindingRepository>();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加身份认证服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddIdentityServices(this IServiceCollection services)
|
|
|
|
|
{
|
|
|
|
|
services
|
|
|
|
|
.AddIdentityCore<AppUser>()
|
|
|
|
|
.AddRoles<AppRole>()
|
|
|
|
|
.AddEntityFrameworkStores<AppDbContext>();
|
|
|
|
|
|
|
|
|
|
services.AddHttpContextAccessor();
|
|
|
|
|
services.AddScoped<ICurrentUserService, CurrentUserService>();
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加自动注册的服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static IServiceCollection AddAutoRegisteredServices(this IServiceCollection services)
|
|
|
|
|
{
|
|
|
|
|
var assembly = typeof(DependencyInjection).Assembly;
|
|
|
|
|
|
|
|
|
|
services
|
|
|
|
|
.Scan(action =>
|
|
|
|
|
{
|
|
|
|
|
action
|
|
|
|
|
.FromAssemblies(assembly)
|
|
|
|
|
.AddClasses(classes => classes.Where(type =>
|
|
|
|
|
!type.Name.Contains("LockHandle") &&
|
|
|
|
|
!type.IsNested))
|
|
|
|
|
.UsingRegistrationStrategy(RegistrationStrategy.Skip)
|
|
|
|
|
.AsImplementedInterfaces()
|
|
|
|
|
.WithScopedLifetime();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加 JWT 服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="services">服务集合</param>
|
|
|
|
|
/// <param name="configuration">配置</param>
|
|
|
|
|
/// <returns>服务集合</returns>
|
|
|
|
|
private static IServiceCollection AddJwtServices(
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
// 配置 JWT 选项
|
|
|
|
|
var jwtOptions = configuration.GetSection(JwtOptions.SectionName).Get<JwtOptions>();
|
|
|
|
|
if (jwtOptions == null)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("JWT配置未找到");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName));
|
|
|
|
|
services.Configure<AuthConfiguration>(configuration.GetSection("Auth"));
|
|
|
|
|
|
|
|
|
|
// 注册 JWT 服务
|
|
|
|
|
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, JwtBearerOptionsSetup>();
|
|
|
|
|
services.AddScoped<IJwtProvider, JwtProvider>();
|
|
|
|
|
services.AddSingleton<IKeyRotationService, KeyRotationService>();
|
|
|
|
|
services.AddHostedService<KeyRotationBackgroundService>();
|
|
|
|
|
services.AddSingleton<IJwtValidationService, JwtValidationService>();
|
|
|
|
|
|
|
|
|
|
// 验证 JWT 配置
|
|
|
|
|
var validationService = new JwtValidationService();
|
|
|
|
|
validationService.ValidateOptions(jwtOptions);
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
}
|