Files
TakeoutSaaS.AdminApi/src/Infrastructure/TakeoutSaaS.Infrastructure/Common/Extensions/DatabaseServiceCollectionExtensions.cs

90 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using TakeoutSaaS.Infrastructure.Common.Options;
using TakeoutSaaS.Infrastructure.Common.Persistence;
using TakeoutSaaS.Shared.Abstractions.Data;
namespace TakeoutSaaS.Infrastructure.Common.Extensions;
/// <summary>
/// 数据访问与多数据源相关的服务注册扩展。
/// </summary>
public static class DatabaseServiceCollectionExtensions
{
/// <summary>
/// 注册数据库基础设施多数据源配置、读写分离、Dapper 执行器)。
/// </summary>
/// <param name="services">服务集合。</param>
/// <param name="configuration">配置源。</param>
/// <returns>服务集合。</returns>
public static IServiceCollection AddDatabaseInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
services.AddOptions<DatabaseOptions>()
.Bind(configuration.GetSection(DatabaseOptions.SectionName))
.ValidateDataAnnotations()
.ValidateOnStart();
services.AddSingleton<IDatabaseConnectionFactory, DatabaseConnectionFactory>();
services.AddScoped<IDapperExecutor, DapperExecutor>();
return services;
}
/// <summary>
/// 为指定 DbContext 注册读写分离的 PostgreSQL 配置,同时提供读上下文工厂。
/// </summary>
/// <typeparam name="TContext">上下文类型。</typeparam>
/// <param name="services">服务集合。</param>
/// <param name="dataSourceName">逻辑数据源名称。</param>
/// <returns>服务集合。</returns>
public static IServiceCollection AddPostgresDbContext<TContext>(
this IServiceCollection services,
string dataSourceName)
where TContext : DbContext
{
services.AddDbContext<TContext>(
(sp, options) =>
{
ConfigureDbContextOptions(sp, options, dataSourceName, DatabaseConnectionRole.Write);
},
contextLifetime: ServiceLifetime.Scoped,
optionsLifetime: ServiceLifetime.Singleton);
services.AddDbContextFactory<TContext>((sp, options) =>
{
ConfigureDbContextOptions(sp, options, dataSourceName, DatabaseConnectionRole.Read);
});
return services;
}
/// <summary>
/// 配置 DbContextOptions应用连接串、命令超时与重试策略。
/// </summary>
/// <param name="serviceProvider">服务提供程序。</param>
/// <param name="optionsBuilder">上下文配置器。</param>
/// <param name="dataSourceName">数据源名称。</param>
/// <param name="role">连接角色。</param>
private static void ConfigureDbContextOptions(
IServiceProvider serviceProvider,
DbContextOptionsBuilder optionsBuilder,
string dataSourceName,
DatabaseConnectionRole role)
{
var connection = serviceProvider
.GetRequiredService<IDatabaseConnectionFactory>()
.GetConnection(dataSourceName, role);
optionsBuilder.UseNpgsql(
connection.ConnectionString,
npgsqlOptions =>
{
npgsqlOptions.CommandTimeout(connection.CommandTimeoutSeconds);
npgsqlOptions.EnableRetryOnFailure(
connection.MaxRetryCount,
TimeSpan.FromSeconds(connection.MaxRetryDelaySeconds),
null);
});
}
}