Healnet.Core 2.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package Healnet.Core --version 2.0.3
                    
NuGet\Install-Package Healnet.Core -Version 2.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Healnet.Core" Version="2.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Healnet.Core" Version="2.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Healnet.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Healnet.Core --version 2.0.3
                    
#r "nuget: Healnet.Core, 2.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Healnet.Core@2.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Healnet.Core&version=2.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Healnet.Core&version=2.0.3
                    
Install as a Cake Tool

Healnet.Core 核心模块

版本: v1.5.0 | TFM: net10.0 | 依赖: Healnet.Common | NuGet: Healnet.Core 1.5.0

概述

Healnet.Core 是 Healnet 微服务框架的核心业务层类库,提供领域驱动设计(DDD)的基础设施、统一异常体系、仓储模式、API 响应格式和通用服务基类。作为框架的业务核心层,为 Infrastructure 层提供接口抽象和业务基础支撑。

核心特性

  • ✅ DDD 实体 - Entity/AggregateRoot/ValueObject 等 DDD 基础类型
  • ✅ 审计实体 - AuditableEntity/SoftDeleteEntity 通用审计字段
  • ✅ 领域事件 - DomainEvent 事件驱动架构支持
  • ✅ 统一异常 - 7 种业务异常类型:Business/NotFound/Validation 等
  • ✅ 仓储模式 - IRepository/IReadOnlyRepository 泛型仓储接口
  • ✅ 工作单元 - IUnitOfWork 事务管理抽象
  • ✅ 服务基类 - BaseService/CrudService 通用 CRUD 服务
  • ✅ API 响应 - ApiResponse/PagedResponse 统一响应格式
  • ✅ 消息队列 - IMessagePublisher/IMessageSubscriber 消息接口抽象
  • ✅ 缓存/日志 - ICacheService/ILoggerService 基础设施接口

核心组件

1. 实体与值对象 (Entities)

类 命名空间 说明
Entity<TKey> Healnet.Core.Entities 实体基类:主键 Id、相等性比较、哈希码
AggregateRoot<TKey> Healnet.Core.Entities 聚合根基类:支持领域事件收集与分发
ValueObject Healnet.Core.Entities 值对象基类:基于属性的值相等性比较
AuditableEntity Healnet.Core.Entities 可审计实体:创建时间、修改时间、创建人、修改人
SoftDeleteEntity Healnet.Core.Entities 软删除实体:IsDeleted 标记 + 删除时间
DomainEvent Healnet.Core.Entities 领域事件基类:事件发生时间戳

2. 异常体系 (Exceptions)

类 错误码 说明
HealnetException 自定义 所有业务异常的基类
BadRequestException 400 请求参数错误
BusinessException 400 业务逻辑异常
NotFoundException 404 资源未找到
ForbiddenException 403 权限不足
UnauthorizedException 401 未授权访问
ValidationException 422 数据验证失败

3. 接口抽象 (Interfaces)

接口 命名空间 说明
IRepository<TEntity, TKey> Healnet.Core.Interfaces 完整仓储接口:CRUD + 分页 + 批量操作
IReadOnlyRepository<TEntity, TKey> Healnet.Core.Interfaces 只读仓储接口:查询 + 条件过滤
IUnitOfWork Healnet.Core.Interfaces 工作单元接口:事务提交与回滚
IService<T> Healnet.Core.Interfaces 服务接口基类
ICacheService Healnet.Core.Interfaces 缓存服务接口
ILoggerService Healnet.Core.Interfaces 日志服务接口
IMessagePublisher Healnet.Core.Interfaces 消息发布接口
IMessageSubscriber Healnet.Core.Interfaces 消息订阅接口

4. 服务基类 (Services)

类 命名空间 说明
BaseService Healnet.Core.Services 服务基类:ID 验证、非空验证、日志记录
CrudService Healnet.Core.Services CRUD 服务基类:增删改查通用实现

5. API 响应 (Responses)

类 命名空间 说明
ApiResponse Healnet.Core.Responses 统一 API 响应:Code/Message/Data/Timestamp/Path
ApiResponse<T> Healnet.Core.Responses 泛型 API 响应:强类型 Data 字段
PagedResponse<T> Healnet.Core.Responses 分页响应:TotalCount/Page/PageSize/Items

6. 其他模块

模块 说明
Middleware/ExceptionHandlerMiddleware 全局异常处理中间件
Filters/IdempotentAttribute 幂等性过滤器
Versioning/ApiVersionAttribute API 版本控制特性
Outbox/OutboxMessage 出站消息(分布式事务 Outbox 模式)
Features CQRS 命令/查询特性定义
Filters 请求过滤器基类
Middleware 中间件抽象
Filtering 过滤功能扩展
Context 上下文抽象

依赖关系

graph LR
    A[Healnet.Core] --> B[Healnet.Common]
    A --> C[Microsoft.Extensions.Logging.Abstractions]
    A --> D[Microsoft.AspNetCore.Http.Abstractions]

使用指南

1. 创建实体

using Healnet.Core.Entities;

// 基础实体
public class User : Entity<long>
{
    public string Name { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
}

// 可审计实体
public class Product : AuditableEntity
{
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
}

// 软删除实体
public class Article : SoftDeleteEntity
{
    public string Title { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;
}

2. 统一异常处理

using Healnet.Core.Exceptions;

// 业务异常
throw new BusinessException("库存不足");

// 资源未找到
throw new NotFoundException($"用户 {userId} 不存在");

// 验证失败
throw new ValidationException(new List<string> { "邮箱格式不正确" });

// 权限不足
throw new ForbiddenException("无权访问此资源");

3. API 响应格式

using Healnet.Core.Responses;

// 成功响应
return Ok(ApiResponse.Success("操作成功"));

// 带数据的成功响应
return Ok(ApiResponse<User>.Success(user, "查询成功"));

// 错误响应
return BadRequest(ApiResponse.Error(400, "参数错误"));

// 分页响应
var paged = PagedResponse<User>.Create(users, page, pageSize, totalCount);
return Ok(paged);

4. 仓储接口

using Healnet.Core.Interfaces;

public interface IUserRepository : IRepository<User, long>
{
    Task<User?> GetByEmailAsync(string email);
    Task<IEnumerable<User>> GetActiveUsersAsync();
}

5. 服务基类

using Healnet.Core.Services;
using Healnet.Core.Interfaces;

public class UserService : BaseService, IUserService
{
    private readonly IRepository<User, long> _repository;

    public UserService(ILoggerService logger, IRepository<User, long> repository)
        : base(logger)
    {
        _repository = repository;
    }

    public async Task<User> GetByIdAsync(long id)
    {
        ValidateId(id); // 内置 ID 验证
        var user = await _repository.GetByIdAsync(id);
        if (user is null)
            throw new NotFoundException($"用户 {id} 不存在");
        return user;
    }
}

6. 全局异常处理中间件

// Program.cs
app.UseMiddleware<ExceptionHandlerMiddleware>();

NuGet 包信息

属性 值
PackageId Healnet.Core
当前版本 1.5.0
目标框架 net10.0
依赖项目 Healnet.Common
许可证 LICENSE
仓库 github.com/healnet/healnet-framework

版本历史

| 版本 | 日期 | 变更说明 | |------|------|----------| | v1.5.0 | 2026-06-16 | 新增 AggregateRoot<T>、ValueObject、DomainEvent;增强 ExceptionHandlerMiddleware 覆盖所有异常类型;移除 Newtonsoft.Json 依赖 | | v1.4.0 | - | 版本统一升级 | }

// 值对象 public class Address : ValueObject { public string Street { get; private set; } public string City { get; private set; } public string Province { get; private set; } public string ZipCode { get; private set; }

private Address() { }

public Address(string street, string city, string province, string zipCode)
{
    Street = street;
    City = city;
    Province = province;
    ZipCode = zipCode;
}

protected override IEnumerable<object> GetEqualityComponents()
{
    yield return Street;
    yield return City;
    yield return Province;
    yield return ZipCode;
}

}

// 强类型枚举 public class OrderStatus : Enumeration<OrderStatus> { public static readonly OrderStatus Pending = new(1, "Pending", "待处理"); public static readonly OrderStatus Paid = new(2, "Paid", "已支付"); public static readonly OrderStatus Completed = new(3, "Completed", "已完成"); public static readonly OrderStatus Cancelled = new(4, "Cancelled", "已取消");

public string Description { get; private set; }

private OrderStatus(int id, string name, string description) : base(id, name)
{
    Description = description;
}

}


### 2. 创建仓储

```csharp
public interface IOrderRepository : IRepository<Order, long>
{
    Task<Order?> GetByOrderNoAsync(string orderNo);
    Task<List<Order>> GetByUserIdAsync(long userId);
    Task<List<Order>> GetOrdersByStatusAsync(OrderStatus status);
}

public class OrderRepository : RepositoryBase<Order, long>, IOrderRepository
{
    public OrderRepository(IDbContext dbContext) : base(dbContext) { }
    
    public async Task<Order?> GetByOrderNoAsync(string orderNo)
    {
        return await FindAsync(o => o.OrderNo == orderNo);
    }
    
    public async Task<List<Order>> GetByUserIdAsync(long userId)
    {
        return await FindAllAsync(o => o.UserId == userId);
    }
    
    public async Task<List<Order>> GetOrdersByStatusAsync(OrderStatus status)
    {
        return await FindAllAsync(o => o.Status == status);
    }
}

3. 创建命令和查询

// 命令
public record CreateOrderCommand(
    long UserId,
    List<OrderItemDto> Items
) : ICommand<long>;

public class CreateOrderCommandHandler : ICommandHandler<CreateOrderCommand, long>
{
    private readonly IOrderRepository _orderRepository;
    private readonly IProductRepository _productRepository;
    private readonly IUnitOfWork _unitOfWork;
    
    public CreateOrderCommandHandler(IOrderRepository orderRepository,
        IProductRepository productRepository,
        IUnitOfWork unitOfWork)
    {
        _orderRepository = orderRepository;
        _productRepository = productRepository;
        _unitOfWork = unitOfWork;
    }
    
    public async Task<long> Handle(CreateOrderCommand command, CancellationToken cancellationToken)
    {
        // 验证产品库存
        foreach (var item in command.Items)
        {
            var product = await _productRepository.GetByIdAsync(item.ProductId);
            if (product == null || product.Stock < item.Quantity)
            {
                throw new BusinessException($"产品 {item.ProductId} 库存不足");
            }
        }
        
        // 创建订单
        var order = new Order
        {
            OrderNo = GenerateOrderNo(),
            UserId = command.UserId
        };
        
        // 添加订单项
        foreach (var item in command.Items)
        {
            var product = await _productRepository.GetByIdAsync(item.ProductId);
            order.AddItem(product, item.Quantity, item.Price);
            
            // 扣减库存
            product.Stock -= item.Quantity;
            await _productRepository.UpdateAsync(product);
        }
        
        // 保存订单
        await _orderRepository.AddAsync(order);
        await _unitOfWork.SaveChangesAsync(cancellationToken);
        
        return order.Id;
    }
    
    private string GenerateOrderNo()
    {
        return $"ORD{DateTime.Now:yyyyMMddHHmmss}{Guid.NewGuid():N[0..4]}";
    }
}

// 查询
public record GetOrderQuery(long OrderId) : IQuery<OrderDto>;

public class GetOrderQueryHandler : IQueryHandler<GetOrderQuery, OrderDto>
{
    private readonly IOrderRepository _orderRepository;
    
    public GetOrderQueryHandler(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }
    
    public async Task<OrderDto> Handle(GetOrderQuery query, CancellationToken cancellationToken)
    {
        var order = await _orderRepository.GetByIdAsync(query.OrderId);
        
        if (order == null)
        {
            throw new NotFoundException("订单不存在");
        }
        
        return new OrderDto
        {
            Id = order.Id,
            OrderNo = order.OrderNo,
            UserId = order.UserId,
            TotalAmount = order.TotalAmount,
            Status = order.Status.Name,
            Items = order.Items.Select(item => new OrderItemDto
            {
                ProductId = item.ProductId,
                Quantity = item.Quantity,
                Price = item.Price
            }).ToList()
        };
    }
}

4. 使用中介者

public class OrderService
{
    private readonly IMediator _mediator;
    
    public OrderService(IMediator mediator)
    {
        _mediator = mediator;
    }
    
    public async Task<long> CreateOrderAsync(CreateOrderCommand command)
    {
        return await _mediator.Send(command);
    }
    
    public async Task<OrderDto> GetOrderAsync(long orderId)
    {
        return await _mediator.Send(new GetOrderQuery(orderId));
    }
}

// Controller
[ApiController]
[Route("api/orders")]
public class OrderController : ControllerBase
{
    private readonly IMediator _mediator;
    
    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }
    
    [HttpPost]
    public async Task<IActionResult> CreateOrder([FromBody] CreateOrderCommand command)
    {
        var orderId = await _mediator.Send(command);
        return CreatedAtAction(nameof(GetOrder), new { id = orderId }, null);
    }
    
    [HttpGet("{id}")]
    public async Task<IActionResult> GetOrder(long id)
    {
        var order = await _mediator.Send(new GetOrderQuery(id));
        return Ok(order);
    }
}

5. 领域事件处理

// 定义领域事件
public record OrderCompletedEvent(Order Order) : IDomainEvent;

// 事件处理器
public class OrderCompletedHandler : IEventHandler<OrderCompletedEvent>
{
    private readonly IEmailService _emailService;
    private readonly IInventoryService _inventoryService;
    
    public OrderCompletedHandler(IEmailService emailService, IInventoryService inventoryService)
    {
        _emailService = emailService;
        _inventoryService = inventoryService;
    }
    
    public async Task Handle(OrderCompletedEvent domainEvent, CancellationToken cancellationToken)
    {
        var order = domainEvent.Order;
        
        // 发送订单完成邮件
        await _emailService.SendOrderCompleteEmail(order.UserId, order.Id);
        
        // 更新库存
        await _inventoryService.UpdateInventory(order.Items);
        
        // 记录审计日志
        // await _auditService.LogOrderCompleted(order);
    }
}

// 事件总线配置
public class EventBusModule
{
    public static void RegisterEventHandlers(IServiceCollection services)
    {
        services.AddScoped<IEventHandler<OrderCompletedEvent>, OrderCompletedHandler>();
        services.AddScoped<IEventHandler<OrderItemAddedEvent>, OrderItemAddedHandler>();
        services.AddScoped<IEventHandler<UserRegisteredEvent>, UserRegisteredHandler>();
    }
}

6. 规格模式

public class OrderByStatusSpecification : Specification<Order>
{
    private readonly OrderStatus _status;
    
    public OrderByStatusSpecification(OrderStatus status)
    {
        _status = status;
    }
    
    public override Expression<Func<Order, bool>> ToExpression()
    {
        return order => order.Status == _status;
    }
}

public class OrdersWithItemsSpecification : Specification<Order>
{
    public override Expression<Func<Order, bool>> ToExpression()
    {
        return order => order.Items.Any();
    }
}

// 组合规格
public class ActiveOrdersSpecification : CompositeSpecification<Order>
{
    public ActiveOrdersSpecification()
        : base(new OrderByStatusSpecification(OrderStatus.Pending), 
              new OrdersWithItemsSpecification())
    {
    }
}

// 使用规格
public class OrderService
{
    private readonly IOrderRepository _repository;
    
    public OrderService(IOrderRepository repository)
    {
        _repository = repository;
    }
    
    public async Task<List<Order>> GetActiveOrdersAsync()
    {
        var spec = new ActiveOrdersSpecification();
        return await _repository.FindAllAsync(spec);
    }
}

7. 异常处理

// 自定义异常
public class BusinessException : Exception
{
    public int ErrorCode { get; }
    
    public BusinessException(string message) : base(message)
    {
        ErrorCode = 400;
    }
    
    public BusinessException(string message, int errorCode) : base(message)
    {
        ErrorCode = errorCode;
    }
}

public class NotFoundException : BusinessException
{
    public NotFoundException(string message) : base(message, 404) { }
}

public class UnauthorizedException : BusinessException
{
    public UnauthorizedException(string message) : base(message, 401) { }
}

public class ForbiddenException : BusinessException
{
    public ForbiddenException(string message) : base(message, 403) { }
}

// 全局异常处理中间件
public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionHandlerMiddleware> _logger;
    
    public ExceptionHandlerMiddleware(RequestDelegate next, ILogger<ExceptionHandlerMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    
    private async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        _logger.LogError(exception, "An unhandled exception occurred.");
        
        var response = new ApiResponse
        {
            Success = false,
            Message = exception.Message
        };
        
        if (exception is BusinessException businessEx)
        {
            context.Response.StatusCode = businessEx.ErrorCode;
            response.Code = businessEx.ErrorCode;
        }
        else
        {
            context.Response.StatusCode = 500;
            response.Code = 500;
            response.Message = "服务器内部错误";
        }
        
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsJsonAsync(response);
    }
}

8. 数据验证

public class CreateOrderCommandValidator : AbstractValidator<CreateOrderCommand>
{
    public CreateOrderCommandValidator()
    {
        RuleFor(x => x.UserId).NotEmpty().GreaterThan(0);
        
        RuleFor(x => x.Items).NotEmpty();
        
        RuleForEach(x => x.Items).ChildRules(items =>
        {
            items.RuleFor(item => item.ProductId).NotEmpty().GreaterThan(0);
            items.RuleFor(item => item.Quantity).NotEmpty().GreaterThan(0);
            items.RuleFor(item => item.Price).NotEmpty().GreaterThan(0);
        });
    }
}

// 验证管道行为
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    private readonly IEnumerable<IValidator<TRequest>> _validators;
    
    public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
    {
        _validators = validators;
    }
    
    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        if (!_validators.Any())
        {
            return await next();
        }
        
        var context = new ValidationContext<TRequest>(request);
        var failures = _validators
            .Select(v => v.Validate(context))
            .SelectMany(result => result.Errors)
            .Where(f => f != null)
            .ToList();
        
        if (failures.Any())
        {
            throw new ValidationException(failures);
        }
        
        return await next();
    }
}

服务注册

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// 添加核心服务
builder.Services.AddCore();

// 添加 MediatR(CQRS)
builder.Services.AddMediatR(cfg => 
{
    cfg.RegisterServicesFromAssembly(typeof(CreateOrderCommand).Assembly);
    cfg.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
});

// 添加验证服务
builder.Services.AddValidatorsFromAssembly(typeof(CreateOrderCommandValidator).Assembly);

var app = builder.Build();

// 注册全局异常处理中间件
app.UseMiddleware<ExceptionHandlerMiddleware>();

app.Run();

依赖包

<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="FluentValidation" Version="11.9.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />

架构说明

┌─────────────────────────────────────────────────────────────┐
│                     Healnet.Core                           │
├─────────────────────────────────────────────────────────────┤
│  Domain Layer                                              │
│  ├── Entities          (Entity, AggregateRoot)             │
│  ├── ValueObjects      (ValueObject, Enumeration)          │
│  ├── DomainEvents      (IDomainEvent)                      │
│  └── Services          (Domain Services)                   │
├─────────────────────────────────────────────────────────────┤
│  Application Layer                                         │
│  ├── Commands          (ICommand, ICommandHandler)         │
│  ├── Queries           (IQuery, IQueryHandler)             │
│  ├── Validators        (FluentValidation)                  │
│  └── Behaviors         (Pipeline Behaviors)                │
├─────────────────────────────────────────────────────────────┤
│  Infrastructure Layer                                      │
│  ├── Repositories      (IRepository, RepositoryBase)       │
│  ├── UnitOfWork        (IUnitOfWork)                       │
│  └── EventBus          (IDomainEventDispatcher)            │
└─────────────────────────────────────────────────────────────┘
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Healnet.Core:

Package Downloads
Healnet.Infrastructure

Healnet.Infrastructure 是 Healnet 框架的基础设施层类库,提供各种基础设施服务的封装和集成,包括 Consul 服务发现、Redis 缓存、RabbitMQ 消息队列、gRPC、Elasticsearch、Milvus 向量数据库、SQLSugar ORM、JWT 认证、YARP 反向代理、OpenTelemetry 可观测性、Serilog 日志框架、ClickHouse 列式数据库等。

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.0.0 0 11/4/2026
4.0.15 0 11/4/2026
4.0.14 44 11/3/2026
4.0.13 45 11/3/2026
4.0.12 49 11/3/2026
4.0.11 57 11/3/2026
4.0.10 175 9/15/2026
4.0.9 184 8/13/2026
4.0.8 132 8/13/2026
4.0.7 146 8/13/2026
4.0.6 118 8/10/2026
4.0.3 131 8/10/2026
4.0.0 157 8/3/2026
3.1.0 144 7/24/2026
3.0.1 144 7/23/2026
3.0.0 140 7/16/2026
2.0.7 138 7/10/2026
2.0.5 143 7/8/2026
2.0.3 145 6/30/2026
2.0.0 148 6/29/2026
Loading failed

v2.0.3: 统一三库版本号;升级目标框架至 net10.0;更新所有依赖包至最新稳定版。v2.0.1: 依赖包版本升级,修复若干已知问题。v2.0.0: 重大版本更新,目标框架从 net8.0 升级至 net10.0,全面更新依赖包版本。