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;
|
2026-05-21 16:45:56 +08:00
|
|
|
|
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>();
|
2026-05-22 17:01:49 +08:00
|
|
|
|
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>();
|
2026-05-21 16:45:56 +08:00
|
|
|
|
services.AddScoped<IFileLibraryService, FileLibraryService>();
|
|
|
|
|
|
services.AddScoped<IFileLibraryEndpointService, FileLibraryEndpointService>();
|
2026-05-22 11:18:47 +08:00
|
|
|
|
services.AddScoped<IFileStreamService, FileStreamService>();
|
|
|
|
|
|
services.AddScoped<IQrCodeService, QrCodeService>();
|
2026-05-21 16:45:56 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|