-
Notifications
You must be signed in to change notification settings - Fork 56
Open
Description
Example
Entity method:
public static User Register(
UserId id,
IUniqueUsername uniqueUsername,
IUniqueEmailAddress uniqueEmailAddress)
{ /* ... */ }
Public interfaces:
public interface IUniqueUsername
{
public string Value { get; }
}
public interface IUniqueEmailAddress
{
public string Value { get; }
}
Domain service:
public sealed class UserService(IUsersUnitOfWork unitOfWork)
{
private readonly IUsersUnitOfWork unitOfWork = unitOfWork;
public async Task<Result<IUniqueEmailAddress>> EnsureUniqueEmailAddressAsync(
EmailAddress emailAddress,
UserId? existingUserId = null)
{
var isUnique = await this.unitOfWork.Users.IsUniqueAsync(
new UserByEmailAddressSpec(emailAddress),
existingUserId);
if (isUnique)
{
return new UniqueEmailAddress(emailAddress.Value);
}
return new Error($"A user with the email address '{emailAddress}' already exists.");
}
public async Task<Result<IUniqueUsername>> EnsureUniqueUsernameAsync(
Username username,
UserId? existingUserId = null)
{
var isUnique = await this.unitOfWork.Users.IsUniqueAsync(
new UserByUsernameSpec(username),
existingUserId);
if (isUnique)
{
return new UniqueUsername(username.Value);
}
return new Error($"A user with the username '{username}' already exists.");
}
private sealed record UniqueEmailAddress(string Value) : IUniqueEmailAddress;
private sealed record UniqueUsername(string Value) : IUniqueUsername;
}
Usage in handler:
public async Task<Result<long>> Handle(
RegisterUserCommand command,
CancellationToken cancellationToken = default)
{
var uniqueUsernameResult = await this.userService.EnsureUniqueUsernameAsync(
Username.From(command.Username));
var uniqueEmailAddressResult = await this.userService.EnsureUniqueEmailAddressAsync(
EmailAddress.From(command.EmailAddress));
var result = Result.Combine(uniqueUsernameResult, uniqueEmailAddressResult);
if (result.IsFailure)
{
return result.Errors;
}
var user = User.Register(
UserId.From(this.idGenerator.CreateId()),
uniqueUsernameResult.Value,
uniqueEmailAddressResult.Value);
this.unitOfWork.Users.Add(user);
await this.unitOfWork.SaveChangesAsync(cancellationToken);
return user.Id;
}
Metadata
Metadata
Assignees
Labels
No labels