Skip to content

快速开发流程

这里介绍了使用本框架的主要开发流程,以帮助您快速上手。

1. 创建领域模型

在领域层创建领域模型,定义领域模型的属性、方法、事件、规则等。

// 定义领域模型
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

//为模型定义强类型ID
public partial record UserId : IInt64StronglyTypedId;

//领域模型
public class User : Entity<UserId>, IAggregateRoot
{
    protected User() { }

    public User(string name, string email)
    {
        Name = name;
        Email = email;
        this.AddDomainEvent(new UserCreatedDomainEvent(this));
    }
    public string Name { get; private set; }
    public string Email { get; private set; }

    public void ChangeEmail(string email)
    {
        Email = email;
        this.AddDomainEvent(new UserEmailChangedDomainEvent(this));
    }
}

定义领域事件

//定义领域事件
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public record UserCreatedDomainEvent(User user) : IDomainEvent;

2. 创建仓储

定义领域模型的仓储接口

//定义仓储接口
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public interface IUserRepository : IRepository<User, UserId>
{
    Task<User> GetByEmailAsync(string email); //可选的自定义查询方法
}

实现仓储接口

//实现仓储接口
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public class UserRepository : Repository<User, UserId>, IUserRepository
{
    public UserRepository(IDbContext dbContext) : base(dbContext)
    {
    }

    public async Task<User> GetByEmailAsync(string email)
    {
        return await this.DbSet.FirstOrDefaultAsync(x => x.Email == email);
    }
}

3. 定义模型与数据库映射关系

//定义模型与数据库映射关系
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using NetCorePal.Extensions.Domain;

namespace YourNamespace;

public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(x => x.Id);
        builder.Property(x => x.Name).IsRequired().HasMaxLength(50);
        builder.Property(x => x.Email).IsRequired().HasMaxLength(50);
    }
}

4. 命令与命令处理器

定义领域模型的命令

//定义领域模型的命令
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public record CreateUserCommand(string Name, string Email) : ICommand<UserId>;

定义领域模型的命令处理器

//定义领域模型的命令处理器
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public class CreateUserCommandHandler(IUserRepository userRepository) : ICommandHandler<CreateUserCommand, UserId>
{
    public async Task<UserId> HandleAsync(CreateUserCommand command)
    {
        var user = new User(command.Name, command.Email);
        await userRepository.AddAsync(user);
        return user.Id;
    }
}

5. 定义webapi接口

在controller中使用IMediator接口处理领域模型的命令

定义RequestDto

//定义RequestDto
namespace YourNamespace;

public record CreateUserRequestDto(string Name, string Email);

定义ResponseDto

//定义ResponseDto
namespace YourNamespace;

public record CreateUserResponseDto(UserId UserId);

定义Controller

//定义Controller
using Microsoft.AspNetCore.Mvc;
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

[ApiController]
[Route("api/[controller]")]

public class UserController(IMediator mediator) : ControllerBase
{
    [HttpPost]
    public async Task<ResponseData<CreateUserResponseDto>> CreateUser(CreateUserRequestDto requestDto)
    {
        var command = new CreateUserCommand(requestDto.Name, requestDto.Email);
        var userId = await _mediator.SendAsync(command);
        return new CreateUserResponseDto(userId).AsResponseData();
    }
}

6. 编写集成测试

编写集成测试,测试领域模型的命令处理器,使用MyWebApplicationFactory来创建测试环境

//编写集成测试
using System.Net.Http.Json;
using System.Threading.Tasks;
using Xunit;
using YourNamespace;
namespace YourNamespace.Tests;

public class UserControllerTests : IClassFixture<MyWebApplicationFactory>
{
    private readonly HttpClient _client;

    public UserControllerTests(MyWebApplicationFactory factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task CreateUserTest()
    {
        var response = await _client.PostAsJsonAsync("/api/User", new CreateUserRequestDto("test", "abc@efg.com"));
        response.EnsureSuccessStatusCode();
        var user = await response.Content.ReadFromJsonAsync<CreateUserResponseDto>();
        Assert.NotNull(user);
        Assert.Equal("test", user.Name);
        Assert.Equal("abc@efg.com", user.Email);
    }   
}

7. 领域事件处理器

定义领域事件处理器

//定义领域事件处理器
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public class UserCreatedDomainEventHandler : IDomainEventHandler<UserCreatedDomainEvent>
{
    public async Task HandleAsync(UserCreatedDomainEvent domainEvent)
    {
        //处理领域事件,发送积分 积分领域

    }
}

8. 定义集成事件

定义集成事件

//定义集成事件
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public record UserCreatedIntegrationEvent(UserId userId) : IIntegrationEvent;

9. 发出集成事件

使用 IIntegrationEventPublisher 发出集成事件

//发出集成事件
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public class UserCreatedDomainEventHandler(IIntegrationEventPublisher integrationEventPublisher) : IDomainEventHandler<UserCreatedDomainEvent>
{
    public async Task HandleAsync(UserCreatedDomainEvent domainEvent)
    {
        //处理领域事件
    }
}

10. 集成事件处理器

定义集成事件处理器

//定义集成事件处理器
using NetCorePal.Extensions.Domain;
namespace YourNamespace;

public class UserCreatedIntegrationEventHandler : IIntegrationEventHandler<UserCreatedIntegrationEvent>
{
    public async Task HandleAsync(UserCreatedIntegrationEvent integrationEvent)
    {
        //处理集成事件
        var cmd = new AddUserScoreCommand(integrationEvent.UserId);
        await _mediator.SendAsync(cmd);
    }
}