Я пытаюсь использовать библиотеку MediatR для реализации шаблона команды в сетевом веб-API моего ядра, однако я не уверен, что делать дальше.
У меня есть ситуация, когда пользователь пытается зарегистрироватьучетной записи, API должен проверить базу данных для компании с доменом, который совпадает с указанным адресом электронной почты, затем прикрепить идентификатор компании к объекту пользователя в качестве внешнего ключа или вернуть ошибку, если с этим доменом не существует никакой компании.
У меня есть все необходимые команды и обработчик для их отдельного выполнения:
GetCompanyByDomainHandler.cs
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Application.Application.Exceptions;
using Application.Domain.Entities;
using Application.Persistence;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Application.Application.Companies.Queries.GetCompanyByDomain
{
public class GetCompanyByDomainHandler
IRequestHandler<GetCompanyByDomainQuery, Company>
{
private readonly ApplicationDbContext _context;
public GetCompanyByDomainHandler(ApplicationDbContext context)
{
_context = context;
}
public async Task<Company> Handle(GetCompanyByDomainQuery request,
CancellationToken cancellationToken)
{
var company = await _context.Companies.Where(c => c.Domain ==
request.Domain).SingleOrDefaultAsync();
if (company != null) {
return company;
}
throw new NotFoundException(nameof(Company), request.Domain);
}
}
}
GetCompanyByDomainQuery.cs
using Application.Domain.Entities;
using MediatR;
namespace Application.Application.Companies.Queries.GetCompanyByDomain
{
public class GetCompanyByDomainQuery : IRequest<Company>
{
public string Domain { get; set; }
}
}
CreateUserCommand.cs
using MediatR;
namespace Application.Application.Users.Commands.CreateUser
{
public class CreateUserCommand : IRequest<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
public int CompanyId { get; set; }
}
}
CreateUserCommandHandler.cs
using MediatR;
using Application.Domain.Entities.Identity;
using Microsoft.AspNetCore.Identity;
using System.Threading;
using System.Threading.Tasks;
using System;
namespace Application.Application.Users.Commands.CreateUser
{
public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, int>
{
private readonly UserManager<User> _userManager;
public CreateUserCommandHandler(UserManager<User> userManager)
{
_userManager = userManager;
}
public async Task<int> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
var entity = new User
{
FirstName = request.FirstName,
LastName = request.LastName,
Email = request.EmailAddress,
UserName = request.EmailAddress,
CompanyId = request.CompanyId
};
var createUserResult = await _userManager.CreateAsync(entity, request.Password);
if (createUserResult.Succeeded)
{
return entity.Id;
}
throw new Exception("failed to create user");
}
}
}
CreateUserCommandValidator.cs
using FluentValidation;
namespace Application.Application.Users.Commands.CreateUser
{
public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
public CreateUserCommandValidator()
{
RuleFor(v => v.Password)
.Equal(v => v.ConfirmPassword).WithName("password").WithMessage("Passwords do not match");
RuleFor(v => v.ConfirmPassword)
.Equal(v => v.Password).WithName("confirmPassword").WithMessage("Passwords do not match");
RuleFor(v => v.EmailAddress)
.NotEmpty().WithName("emailAddress").WithMessage("Email Address is required")
.EmailAddress().WithName("emailAddress").WithMessage("Invalid email address");
RuleFor(v => v.FirstName)
.NotEmpty().WithName("firstName").WithMessage("First Name is required");
RuleFor(v => v.LastName)
.NotEmpty().WithName("lastName").WithMessage("Last Name is required");
}
}
}
AuthenticationController.cs
using System.Threading.Tasks;
using Application.Application.Users.Commands.CreateUser;
using Microsoft.AspNetCore.Mvc;
namespace Application.WebUI.Controllers
{
public class AuthenticationController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> Register([FromBody] CreateUserCommand command)
{
return Ok(Mediator.Send(command));
}
}
}
Но как мне их сделатьчасть одного запроса?