Aplicação - Yago-Captain/GeneralNotes GitHub Wiki
O diretório MyGeneralNotes.Application é a espinha dorsal da lógica de negócios da aplicação. Ele contém os principais casos de uso, validadores e a configuração de mapeamento do AutoMapper. Esses componentes são cruciais para garantir a correta manipulação e transformação dos dados entre diferentes camadas do sistema. A seguir, vamos detalhar os principais componentes e suas responsabilidades dentro deste diretório.
A classe MappingConfig
herda de Profile
, uma classe do AutoMapper. O AutoMapper é uma biblioteca que ajuda a mapear um objeto para outro.
using AutoMapper;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Responses;
namespace MyGeneralNotes.Application.Services.AutoMapper;
public class MappingConfig : Profile
{
public MappingConfig()
{
RequestToEntity();
EntityToRequest();
}
private void RequestToEntity()
{
CreateMap<RequestRegisteredUser, Domain.Entities.User>()
.ForMember(to => to.Password, option => option.Ignore());
CreateMap<RequestRoutine, Domain.Entities.Routine>()
.ForMember(dest => dest.Exercises, opt => opt.MapFrom(to => to.Exercises));
CreateMap<RequestExercise, Domain.Entities.Exercise>();
}
private void EntityToRequest()
{
CreateMap<Domain.Entities.User, ResponseUserProfile>();
CreateMap<Domain.Entities.Routine, ResponseRoutine>();
CreateMap<Domain.Entities.Exercise, ResponseExercice>();
CreateMap<Domain.Entities.Exercise, RequestExercise>();
CreateMap<Domain.Entities.Routine, ResponseRoutinesDashboard>()
.ForMember(dest => dest.ExerciseCount, config => config.MapFrom(to => to.Exercises.Count));
}
}
- O construtor
MappingConfig()
é chamado quando você cria uma nova instância dessa classe. Ele chama os métodosRequestToEntity()
eEntityToRequest()
para configurar os mapeamentos. -
RequestToEntity()
define os mapeamentos de objetos de solicitação para entidades de domínio. Por exemplo, ele mapeiaRequestRegisteredUser
paraUser
, ignorando a propriedadePassword
. -
EntityToRequest()
define os mapeamentos de entidades de domínio para objetos de resposta. Por exemplo, ele mapeiaUser
paraResponseUserProfile
.
A classe PasswordValidator<T>
herda de PropertyValidator<T, string>
, que é uma classe do FluentValidation. O FluentValidation é uma biblioteca que ajuda a validar objetos.
using FluentValidation;
using FluentValidation.Validators;
using MyGeneralNotes.Exceptions;
namespace MyGeneralNotes.Application.SharedValidators;
public class PasswordValidator<T> : PropertyValidator<T, string>
{
public override bool IsValid(ValidationContext<T> context, string password)
{
if (string.IsNullOrWhiteSpace(password))
{
context.MessageFormatter.AppendArgument("ErrorMessage", MessagesException.PASSWORD_EMPTY);
return false;
}
if (password.Length < 6)
{
context.MessageFormatter.AppendArgument("ErrorMessage", MessagesException.EMAIL_OR_PASSWORD_INVALID);
return false;
}
return true;
}
public override string Name => "PasswordValidator";
protected override string GetDefaultMessageTemplate(string errorCode) => "{ErrorMessage}";
}
- O método
IsValid(ValidationContext<T> context, string password)
é chamado para validar uma senha. - Se a senha for nula ou uma string vazia, ele adiciona uma mensagem de erro
PASSWORD_EMPTY
ao contexto de validação e retornafalse
. - Se o comprimento da senha for menor que 6, ele adiciona uma mensagem de erro
EMAIL_OR_PASSWORD_INVALID
ao contexto de validação e retornafalse
. - Se a senha passar em ambas as verificações, ele retorna
true
. -
Name
é uma propriedade que retorna o nome do validador. -
GetDefaultMessageTemplate(string errorCode)
é um método que retorna a mensagem de erro padrão.
Esta interface define um contrato para um caso de uso de registro de usuário.
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Response;
namespace MyGeneralNotes.Application.UseCases.User.Register;
public interface IRegisterUserUseCase
{
public Task<ResponseRegisteredUser> Execute(RequestRegisteredUser request);
}
- Define um método
Execute
que aceita umRequestRegisteredUser
e retorna umTask<ResponseRegisteredUser>
.
Esta classe herda de AbstractValidator<RequestRegisteredUser>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Application.SharedValidators;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Domain.Extensions;
using MyGeneralNotes.Exceptions;
namespace MyGeneralNotes.Application.UseCases.User.Register;
public class RegisterUserValidator : AbstractValidator<RequestRegisteredUser>
{
public RegisterUserValidator()
{
RuleFor(user => user.Name).NotEmpty().WithMessage(MessagesException.NAME_EMPTY);
RuleFor(user => user.Email).NotEmpty().WithMessage(MessagesException.EMAIL_EMPTY);
RuleFor(user => user.Email).EmailAddress().WithMessage(MessagesException.EMAIL_IS_INVALID);
RuleFor(user => user.Password).NotEmpty();
RuleFor(user => user.Password).SetValidator(new PasswordValidator<RequestRegisteredUser>());
When(user => string.IsNullOrWhiteSpace(user.Email).IsFalse(), () =>
{
RuleFor(user => user.Email).EmailAddress().WithMessage(MessagesException.EMAIL_IS_INVALID);
});
}
}
- Define regras de validação para um
RequestRegisteredUser
. - Verifica se o nome, o email e a senha do usuário não estão vazios e se o email é um endereço de email válido.
Esta classe implementa a interface IRegisterUserUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Response;
using MyGeneralNotes.Communication.Responses;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.User;
using MyGeneralNotes.Domain.Security.Cryptography;
using MyGeneralNotes.Domain.Security.Tokens;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.User.Register;
public class RegisterUserUseCase(IUserWriteOnlyRepository userWriteOnlyRepository, IMapper mapper, IPasswordEncripter passwordEncripter, IUnitOfWork unitOfWork, IUserReadOnlyRepository userReadOnlyRepository, IAccessTokenGenerator accesTokenGenerator) : IRegisterUserUseCase
{
private readonly IUserWriteOnlyRepository _userWriteOnlyRepository = userWriteOnlyRepository;
private readonly IMapper _mapper = mapper;
private readonly IPasswordEncripter _passwordEncripter = passwordEncripter;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
private readonly IUserReadOnlyRepository _userReadOnlyRepository = userReadOnlyRepository;
private readonly IAccessTokenGenerator _accesTokenGenerator = accesTokenGenerator;
public async Task<ResponseRegisteredUser> Execute(RequestRegisteredUser request)
{
await ValidateRequest(request);
var user = _mapper.Map<Domain.Entities.User>(request);
user.Password = _passwordEncripter.Encrypt(request.Password);
user.UserIdentifier = Guid.NewGuid();
await _userWriteOnlyRepository.Add(user);
await _unitOfWork.Commit();
return new ResponseRegisteredUser
{
Name = request.Name,
Tokens = new ResponseTokens
{
AccessToken = _accesTokenGenerator.Generate(user.UserIdentifier)
}
};
}
private async Task ValidateRequest(RequestRegisteredUser request)
{
var userValidator = new RegisterUserValidator();
var result = userValidator.Validate(request);
var emailExist = await _userReadOnlyRepository.ExistActiveUserWithEmail(request.Email);
if (emailExist)
result.Errors.Add(new FluentValidation.Results.ValidationFailure(string.Empty, MessagesException.EMAIL_ALREADY_REGISTARED));
if (result.IsValid == false)
{
var errorMenssages = result.Errors.Select(e => e.ErrorMessage).ToList();
throw new ErrorOnValidationException(errorMenssages);
}
}
}
- Contém a lógica para registrar um novo usuário.
- Valida o request usando o
RegisterUserValidator
. - Mapeia o request para um objeto
User
usando o AutoMapper. - Criptografa a senha do usuário usando o
IPasswordEncripter
. - Adiciona o usuário ao repositório usando o
IUserWriteOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
. - Retorna um
ResponseRegisteredUser
que contém o nome do usuário e um token de acesso.
Esta interface define um contrato para um caso de uso de obtenção do perfil do usuário.
using MyGeneralNotes.Communication.Responses;
namespace MyGeneralNotes.Application.UseCases.User.Profile;
public interface IGetUserProfileUseCase
{
public Task<ResponseUserProfile> Execute();
}
- Define um método
Execute
que retorna umTask<ResponseUserProfile>
.
Esta classe implementa a interface IGetUserProfileUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Responses;
using MyGeneralNotes.Domain.Services.LoggedUser;
namespace MyGeneralNotes.Application.UseCases.User.Profile;
public class GetUserProfileUseCase(ILoggedUser logged, IMapper mapper) : IGetUserProfileUseCase
{
private readonly ILoggedUser _logged = logged;
private readonly IMapper _mapper = mapper;
public async Task<ResponseUserProfile> Execute()
{
var user = await _logged.User();
return _mapper.Map<ResponseUserProfile>(user);
}
}
- Contém a lógica para obter o perfil do usuário atualmente logado.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Mapeia o usuário para um
ResponseUserProfile
usando o AutoMapper. - Retorna o
ResponseUserProfile
.
Esta interface define um contrato para um caso de uso de alteração de senha.
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.User.ChangePassword;
public interface IChangePasswordUseCase
{
public Task Execute(RequestChangePassword request);
}
- Define um método
Execute
que aceita umRequestChangePassword
e retorna umTask
.
Esta classe herda de AbstractValidator<RequestChangePassword>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Application.SharedValidators;
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.User.ChangePassword;
public class ChangePasswordValidator : AbstractValidator<RequestChangePassword>
{
public ChangePasswordValidator()
{
RuleFor(x => x.NewPassword).SetValidator(new PasswordValidator<RequestChangePassword>());
}
}
- Define regras de validação para um
RequestChangePassword
. - Verifica se a nova senha do usuário é válida usando o
PasswordValidator
.
Esta classe implementa a interface IChangePasswordUseCase
.
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Domain.Extensions;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.User;
using MyGeneralNotes.Domain.Security.Cryptography;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.User.ChangePassword;
public class ChangePasswordUseCase(ILoggedUser logged, IUserUpdateOnlyRepository repository, IUnitOfWork unitOfWork, IPasswordEncripter passwordEncripter) : IChangePasswordUseCase
{
private readonly ILoggedUser _logged = logged;
private readonly IUserUpdateOnlyRepository _repository = repository;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
private readonly IPasswordEncripter _passwordEncripter = passwordEncripter;
public async Task Execute(RequestChangePassword request)
{
var loggedUser = await _logged.User();
Validate(request, loggedUser);
var user = await _repository.GetById(loggedUser.Id);
user.Password = _passwordEncripter.Encrypt(request.NewPassword);
_repository.Update(user);
await _unitOfWork.Commit();
}
private void Validate(RequestChangePassword request, Domain.Entities.User loggedUser)
{
var result = new ChangePasswordValidator().Validate(request);
var currentPasswordEncripted = _passwordEncripter.Encrypt(request.Password);
if (currentPasswordEncripted.Equals(loggedUser.Password).IsFalse())
result.Errors.Add(new FluentValidation.Results.ValidationFailure(string.Empty, MessagesException.EMAIL_OR_PASSWORD_INVALID));
if (result.IsValid.IsFalse())
throw new ErrorOnValidationException(result.Errors.Select(e => e.ErrorMessage).ToList());
}
}
- Contém a lógica para alterar a senha do usuário atualmente logado.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Valida o request usando o
ChangePasswordValidator
. - Obtém o usuário do repositório usando o
IUserUpdateOnlyRepository
. - Criptografa a nova senha do usuário usando o
IPasswordEncripter
. - Atualiza o usuário no repositório usando o
IUserUpdateOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
.
Esta interface define um contrato para um caso de uso de atualização de usuário.
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.User.Update;
public interface IUpdateUserUseCase
{
public Task Execute(RequestUpdateUser request);
}
- Define um método
Execute
que aceita umRequestUpdateUser
e retorna umTask
.
Esta classe herda de AbstractValidator<RequestUpdateUser>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Domain.Extensions;
using MyGeneralNotes.Exceptions;
namespace MyGeneralNotes.Application.UseCases.User.Update;
public class UpdateUserValidator : AbstractValidator<RequestUpdateUser>
{
public UpdateUserValidator()
{
RuleFor(request => request.Name).NotEmpty().WithMessage(MessagesException.NAME_EMPTY);
RuleFor(request => request.Email).NotEmpty().WithMessage(MessagesException.EMAIL_EMPTY);
When(request => string.IsNullOrWhiteSpace(request.Email).IsFalse(), () =>
{
RuleFor(request => request.Email).EmailAddress().WithMessage(MessagesException.EMAIL_IS_INVALID);
});
}
}
- Define regras de validação para um
RequestUpdateUser
. - Verifica se o nome e o email do usuário não estão vazios e se o email é um endereço de email válido.
Esta classe implementa a interface IUpdateUserUseCase
.
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Domain.Extensions;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.User;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.User.Update;
public class UpdateUserUseCase(ILoggedUser logged, IUserUpdateOnlyRepository repository, IUserReadOnlyRepository userReadOnlyRepository, IUnitOfWork unitOfWork) : IUpdateUserUseCase
{
private readonly ILoggedUser _logged = logged;
private readonly IUserUpdateOnlyRepository _repository = repository;
private readonly IUserReadOnlyRepository _userReadOnlyRepository = userReadOnlyRepository;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
public async Task Execute(RequestUpdateUser request)
{
var loggedUser = await _logged.User();
await Validate(request, loggedUser.Email);
var user = await _repository.GetById(loggedUser.Id);
user.Name = request.Name;
user.Email = request.Email;
_repository.Update(user);
await _unitOfWork.Commit();
}
private async Task Validate(RequestUpdateUser request, string currentEmail)
{
var validator = new UpdateUserValidator();
var result = validator.Validate(request);
if (currentEmail.Equals(request.Email).IsFalse())
{
var userExist = await _userReadOnlyRepository.ExistActiveUserWithEmail(request.Email);
if (userExist)
result.Errors.Add(new FluentValidation.Results.ValidationFailure("email", MessagesException.EMAIL_ALREADY_REGISTARED));
}
if (result.IsValid.IsFalse())
{
var errorMessages = result.Errors.Select(x => x.ErrorMessage).ToList();
throw new ErrorOnValidationException(errorMessages);
}
}
}
- Contém a lógica para atualizar o usuário atualmente logado.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Valida o request usando o
UpdateUserValidator
. - Obtém o usuário do repositório usando o
IUserUpdateOnlyRepository
. - Atualiza o nome e o email do usuário.
- Atualiza o usuário no repositório usando o
IUserUpdateOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
.
RoutineValidator
é uma classe que herda de AbstractValidator<RequestRoutine>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Exceptions;
namespace MyGeneralNotes.Application.UseCases.Routines;
public class RoutineValidator : AbstractValidator<RequestRoutine>
{
public RoutineValidator()
{
RuleFor(r => r.Name).NotEmpty().WithMessage(MessagesException.ROUTINE_NAME_IN_BLANK);
RuleFor(r => r.DayOfWeek).IsInEnum().NotEmpty();
RuleFor(r => r.Exercises).NotEmpty().WithMessage(MessagesException.EXERCISES_IN_BLANK);
RuleForEach(r => r.Exercises).ChildRules(exercices =>
{
exercices.RuleFor(e => e.Name).NotEmpty().WithMessage(MessagesException.EXERCISE_NAME_BLANK);
exercices.RuleFor(e => e.Location).IsInEnum();
exercices.RuleFor(e => e.Charge).NotEmpty().WithMessage(MessagesException.EXERCISE_WEIGHT_IN_WHITE);
exercices.RuleFor(e => e.Repetitions).NotEmpty().WithMessage(MessagesException.EXERCISE_REPETITIONS_BLANK);
exercices.RuleFor(e => e.RestTime).NotEmpty().WithMessage(MessagesException.WAIT_TIME_IN_BLANK);
exercices.RuleFor(e => e.Equipment).NotEmpty().WithMessage(MessagesException.EQUIPMENT_EXERCISE_BLANK);
exercices.RuleFor(e => e.Details).NotEmpty().WithMessage(MessagesException.DETAIL_EXERCISE_BLANK);
});
}
}
- Define regras de validação para um
RequestRoutine
. - Verifica se o nome da rotina, o dia da semana e a lista de exercícios não estão vazios.
- Aplica um conjunto de regras a cada exercício na lista de exercícios.
Esta interface define um contrato para um caso de uso de registro de rotina.
namespace MyGeneralNotes.Application
{
public interface IRegisterRoutineUseCase
{
Task<ResponseRoutine> Execute(RequestRoutine request);
}
}
- Define um método
Execute
que aceita umRequestRoutine
e retorna umTask<ResponseRoutine>
.
Esta classe herda de AbstractValidator<RequestRoutine>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.Routines.Register;
public class RegisterRoutineValidator : AbstractValidator<RequestRoutine>
{
public RegisterRoutineValidator()
{
RuleFor(r => r).SetValidator(new RoutineValidator());
}
}
- Define regras de validação para um
RequestRoutine
. - Inclui as regras do
RoutineValidator
.
Esta classe implementa a interface IRegisterRoutineUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Responses;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.Routine;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.Routines.Register;
public class RegisterRoutineUseCase(IUnitOfWork unitOfWork, IMapper mapper, ILoggedUser logged, IRoutineWriteOnlyRepository repository) : IRegisterRoutineUseCase
{
private readonly IUnitOfWork _unitOfWork = unitOfWork;
private readonly IMapper _mapper = mapper;
private readonly ILoggedUser _logged = logged;
private readonly IRoutineWriteOnlyRepository _repository = repository;
public async Task<ResponseRoutine> Execute(RequestRoutine request)
{
Validate(request);
var loggedUser = await _logged.User();
var routine = _mapper.Map<Domain.Entities.Routine>(request);
routine.UserId = loggedUser.Id;
await _repository.Register(routine);
await _unitOfWork.Commit();
return _mapper.Map<ResponseRoutine>(routine);
}
private static void Validate(RequestRoutine request)
{
var validator = new RegisterRoutineValidator();
var result = validator.Validate(request);
if (!result.IsValid)
{
var errorMenssages = result.Errors.Select(e => e.ErrorMessage).ToList();
throw new ErrorOnValidationException(errorMenssages);
}
}
}
- Contém a lógica para registrar uma nova rotina.
- Valida o request usando o
RegisterRoutineValidator
. - Obtém o usuário atualmente logado usando o
ILoggedUser
. - Mapeia o request para um objeto
Routine
usando o AutoMapper. - Adiciona a rotina ao repositório usando o
IRoutineWriteOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
. - Retorna um
ResponseRoutine
que contém os detalhes da rotina registrada.
Esta interface define um contrato para um caso de uso de atualização de rotina.
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.Routines.Update;
public interface IUpdateRoutineUseCase
{
Task Update(long routineId, RequestRoutine request);
}
- Define um método
Update
que aceita umroutineId
e umRequestRoutine
, e retorna umTask
.
Esta classe herda de AbstractValidator<RequestRoutine>
, que é uma classe do FluentValidation.
using FluentValidation;
using MyGeneralNotes.Communication.Requests;
namespace MyGeneralNotes.Application.UseCases.Routines.Update;
public class UpdateRoutineValidator : AbstractValidator<RequestRoutine>
{
public UpdateRoutineValidator()
{
RuleFor(x => x).SetValidator(new RoutineValidator());
}
}
- Define regras de validação para um
RequestRoutine
. - Inclui as regras do
RoutineValidator
.
Esta classe implementa a interface IUpdateRoutineUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Domain.Entities;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.Routine;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.Routines.Update;
public class UpdateRoutineUseCase(IMapper mapper, IRoutineUpdateOnlyRepository repository, ILoggedUser logged, IUnitOfWork unitOfWork) : IUpdateRoutineUseCase
{
private readonly IMapper _mapper = mapper;
private readonly IRoutineUpdateOnlyRepository _repository = repository;
private readonly ILoggedUser _logged = logged;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
public async Task Update(long routineId, RequestRoutine request)
{
var loggedUser = await _logged.User();
var routine = await _repository.GetById(routineId);
Validate(loggedUser, routine, request);
_mapper.Map(request, routine);
_repository.Update(routine!);
await _unitOfWork.Commit();
}
private static void Validate(Domain.Entities.User loggedUser, Routine? routine, RequestRoutine request)
{
if (routine is null || routine.UserId != loggedUser.Id)
throw new ErrorOnValidationException([MessagesException.ROUTINE_NOT_FOUND]);
var validator = new UpdateRoutineValidator();
var result = validator.Validate(request);
if (!result.IsValid)
{
var errorMenssages = result.Errors.Select(e => e.ErrorMessage).ToList();
throw new ErrorOnValidationException(errorMenssages);
}
}
}
- Contém a lógica para atualizar uma rotina existente.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Obtém a rotina do repositório usando o
IRoutineUpdateOnlyRepository
. - Valida o usuário logado, a rotina e o request usando o método
Validate
. - Mapeia o request para a rotina existente usando o AutoMapper.
- Atualiza a rotina no repositório usando o
IRoutineUpdateOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
.
Esta interface define um contrato para um caso de uso de obtenção de rotina por ID.
using MyGeneralNotes.Communication.Responses;
namespace MyGeneralNotes.Application.UseCases.Routines.GetById;
public interface IGetRoutineByIdUseCase
{
Task<ResponseRoutine> GetRoutineById(long routineId);
}
- Define um método
GetRoutineById
que aceita umroutineId
e retorna umTask<ResponseRoutine>
.
Esta classe implementa a interface IGetRoutineByIdUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Responses;
using MyGeneralNotes.Domain.Entities;
using MyGeneralNotes.Domain.Repositories.Routine;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.Routines.GetById;
public class GetRoutineByIdUseCase(IMapper mapper, IRoutineReadOnlyRepository repositoy, ILoggedUser logged) : IGetRoutineByIdUseCase
{
private readonly IMapper _mapper = mapper;
private readonly IRoutineReadOnlyRepository _repositoy = repositoy;
private readonly ILoggedUser _logged = logged;
public async Task<ResponseRoutine> GetRoutineById(long routineId)
{
var loggedUser = await _logged.User();
var routine = await _repositoy.GetRoutine(routineId);
Validate(loggedUser, routine);
return _mapper.Map<ResponseRoutine>(routine);
}
private static void Validate(Domain.Entities.User loggedUser, Routine? routine)
{
if (routine is null || routine.UserId != loggedUser.Id)
throw new ErrorOnValidationException([MessagesException.ROUTINE_NOT_FOUND]);
}
}
- Contém a lógica para obter uma rotina pelo ID.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Obtém a rotina do repositório usando o
IRoutineReadOnlyRepository
. - Valida o usuário logado e a rotina usando o método
Validate
. - Mapeia a rotina para um
ResponseRoutine
usando o AutoMapper. - Retorna o
ResponseRoutine
.
Esta interface define um contrato para um caso de uso de exclusão de rotina.
namespace MyGeneralNotes.Application.UseCases.Routines.Delete;
public interface IDeleteRoutineUseCase
{
Task Delete(long routineId);
}
- Define um método
Delete
que aceita umroutineId
e retorna umTask
.
Esta classe implementa a interface IDeleteRoutineUseCase
.
using MyGeneralNotes.Domain.Entities;
using MyGeneralNotes.Domain.Repositories;
using MyGeneralNotes.Domain.Repositories.Routine;
using MyGeneralNotes.Domain.Services.LoggedUser;
using MyGeneralNotes.Exceptions;
using MyGeneralNotes.Exceptions.ExceptionsBase;
namespace MyGeneralNotes.Application.UseCases.Routines.Delete;
public class DeleteRoutineUseCase(IRoutineReadOnlyRepository readOnlyRepository, IRoutineWriteOnlyRepository writeOnlyRepository, ILoggedUser logged, IUnitOfWork unitOfWork) : IDeleteRoutineUseCase
{
private readonly IRoutineReadOnlyRepository _readOnlyRepository = readOnlyRepository;
private readonly IRoutineWriteOnlyRepository _writeOnlyRepository = writeOnlyRepository;
private readonly ILoggedUser _logged = logged;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
public async Task Delete(long routineId)
{
var loggedUser = await _logged.User();
var routine = await _readOnlyRepository.GetRoutine(routineId);
Validate(loggedUser, routine);
await _writeOnlyRepository.Delete(routineId);
await _unitOfWork.Commit();
}
private static void Validate(Domain.Entities.User loggedUser, Routine? routine)
{
if (routine is null || routine.UserId != loggedUser.Id)
throw new ErrorOnValidationException([MessagesException.ROUTINE_NOT_FOUND]);
}
}
- Contém a lógica para excluir uma rotina existente.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Obtém a rotina do repositório usando o
IRoutineReadOnlyRepository
. - Valida o usuário logado e a rotina usando o método
Validate
. - Exclui a rotina do repositório usando o
IRoutineWriteOnlyRepository
. - Confirma as alterações usando o
IUnitOfWork
.
Esta interface define um contrato para um caso de uso de obtenção de dashboard.
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Responses;
namespace MyGeneralNotes.Application.UseCases.Dashboard;
public interface IDashboardUseCase
{
Task<ResponseDashboard> GetDashboard(RequestDashboard request);
}
- Define um método
GetDashboard
que aceita umRequestDashboard
e retorna umTask<ResponseDashboard>
.
Esta classe implementa a interface IDashboardUseCase
.
using AutoMapper;
using MyGeneralNotes.Communication.Requests;
using MyGeneralNotes.Communication.Responses;
using MyGeneralNotes.Domain.Repositories.Routine;
using MyGeneralNotes.Domain.Services.LoggedUser;
namespace MyGeneralNotes.Application.UseCases.Dashboard;
public class DashboardUseCase(IMapper mapper, IRoutineReadOnlyRepository repositoy, ILoggedUser logged) : IDashboardUseCase
{
private readonly IMapper _mapper = mapper;
private readonly IRoutineReadOnlyRepository _repositoy = repositoy;
private readonly ILoggedUser _logged = logged;
public async Task<ResponseDashboard> GetDashboard(RequestDashboard request)
{
var loggedUser = await _logged.User();
var routines = await _repositoy.GetAllUserRoutines(loggedUser.Id);
return new ResponseDashboard
{
Routines = _mapper.Map<List<ResponseRoutinesDashboard>>(routines)
};
}
}
- Contém a lógica para obter o dashboard de um usuário.
- Obtém o usuário atualmente logado usando o
ILoggedUser
. - Obtém todas as rotinas do usuário do repositório usando o
IRoutineReadOnlyRepository
. - Mapeia as rotinas para uma lista de
ResponseRoutine
usando o AutoMapper.
using Microsoft.Extensions.DependencyInjection;
using MyGeneralNotes.Application.Services.AutoMapper;
using MyGeneralNotes.Application.UseCases.Dashboard;
using MyGeneralNotes.Application.UseCases.Login.DoLogin;
using MyGeneralNotes.Application.UseCases.Routines.Delete;
using MyGeneralNotes.Application.UseCases.Routines.GetById;
using MyGeneralNotes.Application.UseCases.Routines.Register;
using MyGeneralNotes.Application.UseCases.Routines.Update;
using MyGeneralNotes.Application.UseCases.User.ChangePassword;
using MyGeneralNotes.Application.UseCases.User.Profile;
using MyGeneralNotes.Application.UseCases.User.Register;
using MyGeneralNotes.Application.UseCases.User.Update;
namespace MyGeneralNotes.Application
{
public static class DependencyInjectionExtension
{
public static void AddApplication(this IServiceCollection services)
{
AddAutoMapper(services);
AddUseCases(services);
}
private static void AddAutoMapper(IServiceCollection services)
{
services.AddScoped(opt => new AutoMapper.MapperConfiguration(options =>
{
options.AddProfile(new MappingConfig());
}).CreateMapper());
}
private static void AddUseCases(IServiceCollection services)
{
services.AddScoped<IRegisterUserUseCase, RegisterUserUseCase>();
services.AddScoped<IDoLoginUseCase, DoLoginUseCase>();
services.AddScoped<IGetUserProfileUseCase, GetUserProfileUseCase>();
services.AddScoped<IUpdateUserUseCase, UpdateUserUseCase>();
services.AddScoped<IChangePasswordUseCase, ChangePasswordUseCase>();
services.AddScoped<IDashboardUseCase, DashboardUseCase>();
services.AddScoped<IRegisterRoutineUseCase, RegisterRoutineUseCase>();
services.AddScoped<IGetRoutineByIdUseCase, GetRoutineByIdUseCase>();
services.AddScoped<IUpdateRoutineUseCase, UpdateRoutineUseCase>();
services.AddScoped<IDeleteRoutineUseCase, DeleteRoutineUseCase>();
}
}
}
A classe DependencyInjectionExtension
é responsável por configurar a injeção de dependência para essa camada de aplicação do seu projeto. Ela contém métodos para adicionar serviços ao container de injeção de dependência.
-
AddApplication(this IServiceCollection services):
- Este é um método de extensão para
IServiceCollection
. Ele chama os métodosAddAutoMapper
eAddUseCases
para adicionar as dependências necessárias para a camada de aplicação.
- Este é um método de extensão para
-
AddAutoMapper(IServiceCollection services):
- Este método adiciona o AutoMapper ao container de injeção de dependência. O AutoMapper é uma biblioteca que ajuda a mapear um objeto para outro. Ele configura o AutoMapper para usar o perfil de mapeamento definido na classe
MappingConfig
.
- Este método adiciona o AutoMapper ao container de injeção de dependência. O AutoMapper é uma biblioteca que ajuda a mapear um objeto para outro. Ele configura o AutoMapper para usar o perfil de mapeamento definido na classe
-
AddUseCases(IServiceCollection services):
- Este método adiciona todas as classes de caso de uso ao container de injeção de dependência. Cada caso de uso é registrado com o ciclo de vida Scoped, o que significa que uma instância será criada por solicitação.
Essas classes de caso de uso, validadores e configurações de mapeamento são os pilares fundamentais que sustentam a lógica central de nossa aplicação. Elas desempenham um papel crucial na manipulação eficaz dos dados, garantindo uma comunicação fluida entre os diversos componentes do sistema. Além disso, fornecem uma base sólida para o desenvolvimento, manutenção e expansão contínua do projeto.
Com uma estrutura bem definida e padrões consistentes, esses elementos simplificam não apenas o fluxo de trabalho dos desenvolvedores, mas também a compreensão e colaboração em equipe. Ao adotar essas práticas, estamos investindo na robustez e na adaptabilidade da aplicação, preparando-a para enfrentar os desafios futuros.