using Dpz.Core.Entity.Base.PublicStruct;
using Dpz.Core.Public.ViewModel.Request;
using Dpz.Core.Public.ViewModel.Response;

namespace Dpz.Core.Service.RepositoryServiceImpl;

/// <summary>
/// 拦截规则管理。读走 [Cache],写后由装饰器失效,判定端下次 GetAllAsync 即读到新规则
/// </summary>
public class InterceptRuleAdminService(IRepository<InterceptRule> repository, IMapper mapper)
    : IInterceptRuleAdminService
{
    /// <inheritdoc />
    [Cache(ExpirationSeconds = ExpirationTime.Month)]
    public async Task<List<InterceptRuleResponse>> GetAllAsync(
        CancellationToken cancellationToken = default
    )
    {
        var rules = await repository.SearchFor(_ => true).ToListAsync(cancellationToken);
        return mapper.Map<List<InterceptRuleResponse>>(rules);
    }

    /// <inheritdoc />
    [InvalidateCache(Methods = [nameof(GetAllAsync)])]
    public async Task AddAsync(
        InterceptRuleSaveRequest request,
        CancellationToken cancellationToken = default
    )
    {
        ValidateRequest(request);

        var entity = new InterceptRule
        {
            Type = request.Type,
            Pattern = request.Pattern,
            Key = request.Key,
        };
        await repository.InsertAsync(entity, cancellationToken);
    }

    /// <inheritdoc />
    [InvalidateCache(Methods = [nameof(GetAllAsync)])]
    public async Task UpdateAsync(
        InterceptRuleEditRequest request,
        CancellationToken cancellationToken = default
    )
    {
        ValidateRequest(request);

        if (!ObjectId.TryParse(request.Id, out var oid))
        {
            throw new ArgumentException($"非法的拦截规则标识: {request.Id}");
        }

        var entity = await repository.FindAsync(oid, cancellationToken);
        if (entity == null)
        {
            throw new InvalidOperationException($"拦截规则不存在: {request.Id}");
        }

        entity.Type = request.Type;
        entity.Pattern = request.Pattern;
        entity.Key = request.Key;
        await repository.UpdateAsync(entity, cancellationToken);
    }

    /// <inheritdoc />
    [InvalidateCache(Methods = [nameof(GetAllAsync)])]
    public async Task DeleteAsync(string id, CancellationToken cancellationToken = default)
    {
        if (!ObjectId.TryParse(id, out var oid))
        {
            throw new ArgumentException($"非法的拦截规则标识: {id}");
        }

        await repository.DeleteAsync(oid, cancellationToken);
    }

    /// <summary>
    /// 校验入参
    /// </summary>
    private static void ValidateRequest(InterceptRuleSaveRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Pattern))
        {
            throw new ArgumentException("拦截规则匹配模式不能为空");
        }

        if (!Enum.IsDefined(request.Type))
        {
            throw new ArgumentException($"非法的拦截类型: {request.Type}");
        }

        if (
            request.Type is InterceptType.Header or InterceptType.QueryParameter
            && string.IsNullOrWhiteSpace(request.Key)
        )
        {
            throw new ArgumentException("Header 与 QueryParameter 类型必须指定键名");
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个 拦截规则管理服务 的实现类,用于管理系统中的拦截规则(InterceptRule)。该服务实现了完整的 CRUD 操作,并使用了缓存机制来优化性能。

核心特性

1. 依赖注入 (Primary Constructor)

public class InterceptRuleAdminService(IRepository<InterceptRule> repository, IMapper mapper)

使用 C# 12 的主构造函数语法,注入了:

  • IRepository<InterceptRule> - 数据仓储,用于数据库操作
  • IMapper - 对象映射器(可能是 AutoMapper),用于实体与 DTO 之间的转换

2. 缓存策略

读操作缓存

[Cache(ExpirationSeconds = ExpirationTime.Month)]
public async Task<List<InterceptRuleResponse>> GetAllAsync(...)
  • 使用 [Cache] 特性装饰器,查询结果会被缓存一个月
  • 减少数据库查询,提升读取性能

写操作失效缓存

[InvalidateCache(Methods = [nameof(GetAllAsync)])]
  • AddAsyncUpdateAsyncDeleteAsync 方法上使用
  • 每次写操作后自动清除 GetAllAsync 的缓存
  • 确保客户端下次调用 GetAllAsync 时能读取到最新数据

3. 业务方法

GetAllAsync - 获取所有规则

var rules = await repository.SearchFor(_ => true).ToListAsync(cancellationToken);
return mapper.Map<List<InterceptRuleResponse>>(rules);
  • 查询所有拦截规则(_ => true 表示无过滤条件)
  • 将实体映射为响应 DTO

AddAsync - 添加规则

  • 先进行参数验证
  • 创建新实体并插入数据库
  • 自动失效缓存

UpdateAsync - 更新规则

  • 验证请求参数
  • 解析并验证 ObjectId(MongoDB 风格的 ID)
  • 检查实体是否存在
  • 更新属性并保存
  • 自动失效缓存

DeleteAsync - 删除规则

  • 验证 ID 格式
  • 直接删除
  • 自动失效缓存

4. 参数校验逻辑

ValidateRequest 方法实现了业务规则验证:

private static void ValidateRequest(InterceptRuleSaveRequest request)

验证规则包括:

  1. Pattern 不能为空 - 拦截规则必须有匹配模式
  2. Type 必须是有效的枚举值 - 使用 Enum.IsDefined 检查
  3. 特定类型需要 Key - 当拦截类型为 HeaderQueryParameter 时,必须指定键名

设计模式

  1. 仓储模式 (Repository Pattern) - 抽象数据访问层
  2. 装饰器模式 (Decorator Pattern) - 通过特性实现缓存和缓存失效
  3. DTO 模式 - 使用 Request/Response 对象分离领域模型和 API 契约

优点

  • ✅ 缓存机制提升性能
  • ✅ 写操作自动失效缓存,保证数据一致性
  • ✅ 清晰的职责分离
  • ✅ 完善的参数验证
  • ✅ 支持异步和取消令牌

这是一个设计良好、符合现代 .NET 开发最佳实践的服务实现。

评论加载中...