using Dpz.Core.Public.ViewModel.Response;
using Dpz.Core.WebApi.MessagePackFormatters;
using MessagePack.Resolvers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;

namespace Dpz.Core.WebApi;

/// <summary>
/// Tools Extensions
/// </summary>
public static class ToolsExtensions
{
    /// <summary>
    /// 生成翻页元数据
    /// </summary>
    /// <param name="pagedList"></param>
    /// <param name="header"></param>
    /// <returns></returns>
    public static void AddPaginationMetadata(this IPagedList pagedList, IHeaderDictionary header)
    {
        var paginationMetadata = new
        {
            currentPage = pagedList.CurrentPageIndex,
            totalCount = pagedList.TotalItemCount,
            pageSize = pagedList.PageSize,
            totalPages = pagedList.TotalPageCount,
            startItemIndex = pagedList.StartItemIndex,
            endItemIndex = pagedList.EndItemIndex,
        };
        var json = JsonSerializer.Serialize(paginationMetadata);
        header.Append("X-Pagination", json);
    }

    /// <param name="builder"></param>
    extension(IApplicationBuilder builder)
    {
        /// <summary>
        /// 使用Response header中间件
        /// </summary>
        /// <returns></returns>
        public IApplicationBuilder UseResponseHeaders()
        {
            return builder.UseMiddleware<HttpResponseHeaderHandel>();
        }

        /// <summary>
        /// 请求记录中间件
        /// </summary>
        /// <returns></returns>
        public IApplicationBuilder UseRequestRecord()
        {
            return builder.UseMiddleware<HttpRequestRecord>();
        }

        /// <summary>
        /// 日期格式化中间件
        /// </summary>
        /// <returns></returns>
        public IApplicationBuilder UseDateTimeLocalFormat()
        {
            return builder.UseMiddleware<DateTimeFormattingMiddleware>();
        }
    }

    /// <summary>
    /// 删除音乐文件
    /// </summary>
    /// <param name="objectStorageService"></param>
    /// <param name="musicResponse"></param>
    /// <exception cref="ArgumentNullException"></exception>
    /// <exception cref="ArgumentException"></exception>
    public static async Task DeleteMusicAsync(
        this IObjectStorageOperation objectStorageService,
        MusicResponse musicResponse
    )
    {
        if (musicResponse == null)
        {
            throw new ArgumentNullException(nameof(musicResponse));
        }

        if (string.IsNullOrEmpty(musicResponse.MusicUrl))
        {
            throw new ArgumentException(
                "property MusicUrl is empty or null",
                nameof(musicResponse.MusicUrl)
            );
        }

        await objectStorageService.DeleteAsync(musicResponse.MusicUrl);

        if (!string.IsNullOrEmpty(musicResponse.CoverUrl))
        {
            await objectStorageService.DeleteAsync(musicResponse.CoverUrl);
        }

        if (!string.IsNullOrEmpty(musicResponse.LyricUrl))
        {
            await objectStorageService.DeleteAsync(musicResponse.LyricUrl);
        }
    }

    /// <summary>
    /// 添加MessagePack序列化
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="setup"></param>
    /// <returns></returns>
    public static IMvcBuilder AddMessagePackSerializerFormatters(
        this IMvcBuilder builder,
        Action<MessagePackFormatterOptions>? setup = null
    )
    {
        builder.Services.Configure<MessagePackFormatterOptions>(o =>
        {
            o.FormatterResolver ??= ContractlessStandardResolver.Instance;

            setup?.Invoke(o);
        });

        builder.Services.TryAddEnumerable(
            ServiceDescriptor.Transient<
                IConfigureOptions<MvcOptions>,
                MessagePackFormatterMvcOptionsSetup
            >()
        );
        return builder;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 ASP.NET Core Web API 的工具扩展类文件,提供了一系列静态扩展方法来增强框架功能。

主要功能模块

1. 分页元数据扩展 (AddPaginationMetadata)

public static void AddPaginationMetadata(this IPagedList pagedList, IHeaderDictionary header)
  • 作用:将分页信息添加到 HTTP 响应头中
  • 实现:创建包含当前页、总数、页大小等信息的匿名对象,序列化为 JSON 后添加到 X-Pagination 响应头
  • 用途:前端可从响应头获取分页元数据,无需从响应体解析

2. 中间件扩展 (extension(IApplicationBuilder builder))

提供三个中间件注册方法:

  • UseResponseHeaders():注册响应头处理中间件
  • UseRequestRecord():注册请求记录中间件(可能用于日志/审计)
  • UseDateTimeLocalFormat():注册日期时间格式化中间件

⚠️ 语法问题:extension 应为 public static class 的方法,这里使用了非标准语法(可能是局部函数或新特性)

3. 对象存储扩展 (DeleteMusicAsync)

public static async Task DeleteMusicAsync(
    this IObjectStorageOperation objectStorageService,
    MusicResponse musicResponse)
  • 作用:删除音乐相关文件(音乐文件、封面、歌词)
  • 参数验证:
    • 检查 musicResponse 非空
    • 检查 MusicUrl 非空(必需)
  • 删除逻辑:
    • 必删:音乐文件
    • 可选删:封面和歌词(如果存在)

4. MessagePack 序列化配置 (AddMessagePackSerializerFormatters)

public static IMvcBuilder AddMessagePackSerializerFormatters(
    this IMvcBuilder builder,
    Action<MessagePackFormatterOptions>? setup = null)
  • 作用:为 MVC 添加 MessagePack 序列化支持
  • 配置:
    • 默认使用 ContractlessStandardResolver(无需特性标注即可序列化)
    • 支持自定义配置回调
  • 注册:通过 IConfigureOptions<MvcOptions> 集成到 MVC 管道

技术特点

  1. 扩展方法模式:所有方法都是扩展方法,增强了代码可读性
  2. 依赖注入集成:使用 TryAddEnumerable 避免重复注册
  3. 异步编程:对象存储操作使用异步方法
  4. 参数验证:包含完整的异常处理和参数校验
  5. 可配置性:提供可选的配置委托参数

使用场景示例

// 分页响应
pagedList.AddPaginationMetadata(Response.Headers);

// 中间件注册
app.UseResponseHeaders()
   .UseRequestRecord()
   .UseDateTimeLocalFormat();

// 删除音乐
await objectStorage.DeleteMusicAsync(musicDto);

// 添加 MessagePack
services.AddControllers()
        .AddMessagePackSerializerFormatters(opt => {
            // 自定义配置
        });
评论加载中...