FileShare/FileShare-API/Configuration/ServicesConfiguration.cs

96 lines
4.4 KiB
C#
Raw Normal View History

2026-05-22 14:29:22 +08:00
using FileShare_API.Authentication;
using FileShare_API.Services;
using FileShare_EFCore.Database;
using FileShare_Services.Core;
using FileShare_Services.Endpoints;
using FileShare_Services.Services;
using FileShare_Services.Services.AuthService;
using FileShare_Services.Services.FileLibrary;
using FileShare_Services.Services.QrCode;
using Microsoft.AspNetCore.DataProtection;
2026-05-21 15:52:36 +08:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
2026-05-22 14:29:22 +08:00
namespace FileShare_API.Configuration
2026-05-21 15:52:36 +08:00
{
/// <summary>
/// API 项目服务配置扩展类,负责注册数据库、鉴权、业务服务和统一端点。
/// </summary>
public static class ServicesConfiguration
{
/// <summary>
/// 注册统一端点及其依赖的服务(含数据库)。
2026-05-22 14:29:22 +08:00
/// 所有业务端点定义在 FileShare-Services/Endpoints/AppEndpoints.cs。
2026-05-21 15:52:36 +08:00
/// </summary>
public static IServiceCollection AddUnifiedApiServices(this IServiceCollection services, IConfiguration configuration)
{
// ---- 数据库 ----
// 从 appsettings.json 读取 DatabaseConfiguration 节
// 注册默认数据库提供程序SQLite / MySQL / PostgreSQL / SqlServer
DatabaseProviderRegistry.RegisterDefaults();
var databaseConfig = configuration
.GetSection(nameof(DatabaseConfiguration))
.Get<DatabaseConfiguration>()
?? DatabaseConfiguration.ForSQLite("app.db");
// 注册 AppDataContext共享数据上下文
services.AddAppDatabase<AppDataContext>(databaseConfig);
// ---- 业务服务 ----
services.AddScoped<WeatherForecastService>();
var thumbnailOptions = configuration
.GetSection(nameof(ThumbnailStorageOptions))
.Get<ThumbnailStorageOptions>()
?? new ThumbnailStorageOptions();
services.AddSingleton(thumbnailOptions);
services.AddSingleton<IVideoThumbnailService>(sp =>
new VideoThumbnailService(sp.GetRequiredService<ThumbnailStorageOptions>()));
services.AddScoped<IThumbnailStreamService, ThumbnailStreamService>();
services.AddScoped<IFileLibraryService, FileLibraryService>();
services.AddScoped<IFileLibraryEndpointService, FileLibraryEndpointService>();
services.AddScoped<IFileStreamService, FileStreamService>();
services.AddScoped<IQrCodeService, QrCodeService>();
services.Configure<FileLibraryScanOptions>(configuration.GetSection(nameof(FileLibraryScanOptions)));
services.AddHostedService<FileLibraryScanHostedService>();
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(AppContext.BaseDirectory, "data-protection-keys")));
2026-05-21 15:52:36 +08:00
// ---- API 鉴权 ----
var jwtSection = configuration.GetSection("Jwt");
services.Configure<JwtOptions>(jwtSection);
var jwtOptions = jwtSection.Get<JwtOptions>() ?? new JwtOptions();
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtOptions.Issuer,
ValidAudience = jwtOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SigningKey)),
ClockSkew = TimeSpan.FromMinutes(1),
};
});
services.AddAuthorization();
services.AddScoped<JwtTokenService>();
services.AddScoped<RefreshTokenService>();
services.AddScoped<IApiAuthEndpointService, ApiAuthEndpointService>();
// ---- 统一端点 ----
var endpointBuilder = new ServiceEndpointBuilder();
AppEndpoints.Configure(endpointBuilder);
AuthEndpoints.ConfigureApi(endpointBuilder);
var endpoints = endpointBuilder.Build();
services.AddSingleton(endpoints);
return services;
}
}
}