FileShare/FileShare-API/Configuration/ServicesConfiguration.cs
lq1405 27e4029f4a feat: 新增可配置的文件库扫描日志记录及缩略图清理功能
- 为文件库的定时轮询及根目录扫描过程,新增扫描生​​命周期日志
- 允许通过 `appsettings` 配置文件,自定义定时扫描的轮询间隔
- 当检测到媒体文件已被删除时,自动清理过期的缩略图映射记录及对应的缩略图文件
2026-05-22 20:09:22 +08:00

96 lines
4.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 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;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace FileShare_API.Configuration
{
/// <summary>
/// API 项目服务配置扩展类,负责注册数据库、鉴权、业务服务和统一端点。
/// </summary>
public static class ServicesConfiguration
{
/// <summary>
/// 注册统一端点及其依赖的服务(含数据库)。
/// 所有业务端点定义在 FileShare-Services/Endpoints/AppEndpoints.cs。
/// </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")));
// ---- 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;
}
}
}