diff --git a/Liber_Incantamentum.Application/DTOs/Mage/MageDtoUpdate.cs b/Liber_Incantamentum.Application/DTOs/Mage/MageDtoUpdate.cs index a6f6a4c..364e29d 100644 --- a/Liber_Incantamentum.Application/DTOs/Mage/MageDtoUpdate.cs +++ b/Liber_Incantamentum.Application/DTOs/Mage/MageDtoUpdate.cs @@ -1,4 +1,6 @@ -namespace Liber_Incantamentum.Application.DTOs.Mage +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.DTOs.Mage { public class MageDtoUpdate { @@ -6,5 +8,6 @@ public required string Name { get; set; } public required string Rank { get; set; } public required string Specialisation { get; set; } + public ICollection Spells { get; set; } = new List(); } } diff --git a/Liber_Incantamentum.Application/DTOs/Spell/SpellDtoFilter.cs b/Liber_Incantamentum.Application/DTOs/Spell/SpellDtoFilter.cs index 0112012..1613788 100644 --- a/Liber_Incantamentum.Application/DTOs/Spell/SpellDtoFilter.cs +++ b/Liber_Incantamentum.Application/DTOs/Spell/SpellDtoFilter.cs @@ -2,7 +2,7 @@ { public class SpellDtoFilter { - public Guid Id { get; set; } + public Guid? Id { get; set; } public string? Name { get; set; } public string? Description { get; set; } public string? Type { get; set; } diff --git a/Liber_Incantamentum.Application/Exceptions/AlreadyExistingException.cs b/Liber_Incantamentum.Application/Exceptions/AlreadyExistingException.cs new file mode 100644 index 0000000..3f78eab --- /dev/null +++ b/Liber_Incantamentum.Application/Exceptions/AlreadyExistingException.cs @@ -0,0 +1,11 @@ +namespace Liber_Incantamentum.Application.Exceptions +{ + public class AlreadyExistingException : Exception + { + public AlreadyExistingException() { } + public AlreadyExistingException(string message) : base(message) { } + public AlreadyExistingException(string? message, Exception? innerException) : base(message, innerException) { } + } +} + + diff --git a/Liber_Incantamentum.Application/Exceptions/ValidationException.cs b/Liber_Incantamentum.Application/Exceptions/ValidationException.cs deleted file mode 100644 index 6245c23..0000000 --- a/Liber_Incantamentum.Application/Exceptions/ValidationException.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Liber_Incantamentum.Application.Exceptions -{ - public class ValidationException : Exception - { - public ValidationException() { } - public ValidationException(string message) : base(message) { } - public ValidationException(string? message, Exception? innerException) : base(message, innerException) { } - } -} diff --git a/Liber_Incantamentum.Application/Interfaces/Generals/ISpellService.cs b/Liber_Incantamentum.Application/Interfaces/Generals/ISpellService.cs deleted file mode 100644 index ed44c64..0000000 --- a/Liber_Incantamentum.Application/Interfaces/Generals/ISpellService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Liber_Incantamentum.Application.DTOs.Mage; -using Liber_Incantamentum.Application.DTOs.Spell; - -namespace Liber_Incantamentum.Application.Interfaces.Generals -{ - public interface ISpellService - { - Task?> GetAllSpellAsync(SpellDtoFilter filter); - Task UpdateSpellAsync(SpellDtoUpdate dto); - Task DeleteSpellAsync(Guid id); - Task AddSpellAsync(SpellDtoCreate dto); - Task GetSpellByIdAsync(Guid id); - } -} \ No newline at end of file diff --git a/Liber_Incantamentum.Application/Interfaces/Generals/IMageService.cs b/Liber_Incantamentum.Application/Interfaces/IMageService.cs similarity index 57% rename from Liber_Incantamentum.Application/Interfaces/Generals/IMageService.cs rename to Liber_Incantamentum.Application/Interfaces/IMageService.cs index da7f0ef..95739fa 100644 --- a/Liber_Incantamentum.Application/Interfaces/Generals/IMageService.cs +++ b/Liber_Incantamentum.Application/Interfaces/IMageService.cs @@ -1,13 +1,13 @@ using Liber_Incantamentum.Application.DTOs.Mage; -namespace Liber_Incantamentum.Application.Interfaces.Generals +namespace Liber_Incantamentum.Application.Interfaces { public interface IMageService { - Task?> GetAllMageAsync(MageDtoFilter filter); + Task> GetAllMageAsync(MageDtoFilter filter); Task UpdateMageAsync(MageDtoUpdate dto); Task DeleteMageAsync(Guid id); Task AddMageAsync(MageDtoCreate dto); - Task GetMageByIdAsync(Guid id); + Task? GetMageByIdAsync(Guid id); } } diff --git a/Liber_Incantamentum.Application/Interfaces/ISpellService.cs b/Liber_Incantamentum.Application/Interfaces/ISpellService.cs new file mode 100644 index 0000000..8d59733 --- /dev/null +++ b/Liber_Incantamentum.Application/Interfaces/ISpellService.cs @@ -0,0 +1,13 @@ +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.Interfaces +{ + public interface ISpellService + { + Task> GetAllSpellAsync(SpellDtoFilter filter); + Task UpdateSpellAsync(SpellDtoUpdate dto); + Task DeleteSpellAsync(Guid id); + Task AddSpellAsync(SpellDtoCreate dto); + Task? GetSpellByIdAsync(Guid id); + } +} \ No newline at end of file diff --git a/Liber_Incantamentum.Application/Interfaces/Mappings/IMapper.cs b/Liber_Incantamentum.Application/Interfaces/Mappings/IMapper.cs deleted file mode 100644 index 64d5849..0000000 --- a/Liber_Incantamentum.Application/Interfaces/Mappings/IMapper.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Liber_Incantamentum.Application.DTOs.Mage; -using Liber_Incantamentum.Application.DTOs.Spell; -using Liber_Incantamentum.Domain.Entities; -using Liber_Incantamentum.Domain.Filter; - -namespace Liber_Incantamentum.Application.Interfaces.Mappings -{ - public interface IMapper - { - Mage MapMageDtoCreateToMageEntity(MageDtoCreate value); - MageFilter MapMageDtoFilterToMageFilter(MageDtoFilter value); - Mage MapMageDtoUpdateToMageEntity(MageDtoUpdate value); - ICollection? MapMageEntityCollectionToMageDtoCollection(ICollection? value); - MageDto mapMageEntityToMageDto(Mage mage); - Spell MapSpellDtoCreateToSpellEntity(SpellDtoCreate value); - SpellFilter MapSpellDtoFilterToSpellFilter(SpellDtoFilter value); - Spell MapSpellDtoUpdateToSpellEntity(SpellDtoUpdate value); - ICollection? MapSpellEntityCollectionToSpellDtoCollection(ICollection? value); - SpellDto mapSpellEntityToSpellDto(Spell spell); - } -} diff --git a/Liber_Incantamentum.Application/Interfaces/Validations/IValidator.cs b/Liber_Incantamentum.Application/Interfaces/Validations/IValidator.cs deleted file mode 100644 index 8b968f1..0000000 --- a/Liber_Incantamentum.Application/Interfaces/Validations/IValidator.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Liber_Incantamentum.Application.DTOs.Mage; -using Liber_Incantamentum.Application.DTOs.Spell; - -namespace Liber_Incantamentum.Application.Interfaces.Validations -{ - public interface IValidator - { - void ValidateGuid(Guid value); - void ValidateMageDto(MageDto value); - void ValidateMageDtoCreate(MageDtoCreate value); - void ValidateMageDtoUpdate(MageDtoUpdate value); - void ValidateMageDtoFilter(MageDtoFilter value); - void ValidateSpellDto(SpellDto value); - void ValidateSpellDtoCreate(SpellDtoCreate value); - void ValidateSpellDtoUpdate(SpellDtoUpdate value); - void ValidateSpellDtoFilter(SpellDtoFilter value); - } -} diff --git a/Liber_Incantamentum.Application/Liber_Incantamentum.Application.csproj b/Liber_Incantamentum.Application/Liber_Incantamentum.Application.csproj index 6031e6c..2c768fb 100644 --- a/Liber_Incantamentum.Application/Liber_Incantamentum.Application.csproj +++ b/Liber_Incantamentum.Application/Liber_Incantamentum.Application.csproj @@ -10,4 +10,9 @@ + + + + + diff --git a/Liber_Incantamentum.Application/Services/Generals/MageService.cs b/Liber_Incantamentum.Application/Services/Generals/MageService.cs index 2c8459c..b2d5ef6 100644 --- a/Liber_Incantamentum.Application/Services/Generals/MageService.cs +++ b/Liber_Incantamentum.Application/Services/Generals/MageService.cs @@ -1,51 +1,84 @@ -using Liber_Incantamentum.Application.DTOs.Mage; -using Liber_Incantamentum.Application.Interfaces.Generals; -using Liber_Incantamentum.Application.Interfaces.Mappings; -using Liber_Incantamentum.Application.Interfaces.Validations; +using AutoMapper; +using Liber_Incantamentum.Application.DTOs.Mage; +using Liber_Incantamentum.Application.Exceptions; +using Liber_Incantamentum.Application.Interfaces; +using Liber_Incantamentum.Domain.Entities; +using Liber_Incantamentum.Domain.Filter; using Liber_Incantamentum.Domain.Repositories; namespace Liber_Incantamentum.Application.Services.Generals { public class MageService : IMageService { - private IValidator _validator; - private IMageRepository _mageRepository; - private IMapper _mapper; - public MageService(IMapper mapper, IMageRepository mageRepository, IValidator validator) + private readonly IMageRepository _mageRepository; + private readonly IMapper _mapper; + public MageService(IMageRepository mageRepository, IMapper mapper) { - _mapper = mapper; _mageRepository = mageRepository; - _validator = validator; + _mapper = mapper; } public async Task AddMageAsync(MageDtoCreate dto) { - _validator.ValidateMageDtoCreate(dto); - return await _mageRepository.AddMageAsync(_mapper.MapMageDtoCreateToMageEntity(dto)); + if (dto == null) + { + throw new ArgumentNullException("The DTO received is null"); + } + var alreadyExistingMage = await GetAllMageAsync(new MageDtoFilter { Name = dto.Name, Rank = dto.Rank, Specialisation = dto.Specialisation }); + if (alreadyExistingMage.Any()) + { + throw new AlreadyExistingException("This mage does already exists"); + } + return await _mageRepository.AddMageAsync(_mapper.Map(dto)); } public async Task DeleteMageAsync(Guid id) { - _validator.ValidateGuid(id); + if (id == Guid.Empty) + { + throw new ArgumentNullException("The id is null"); + } + var alreadyExistingMage = await GetAllMageAsync(new MageDtoFilter { Id = id }); + if (!alreadyExistingMage.Any()) + { + throw new NotFoundException("This mage does not exists"); + } return await _mageRepository.DeleteMageAsync(id); } - public async Task?> GetAllMageAsync(MageDtoFilter filter) + public async Task> GetAllMageAsync(MageDtoFilter filter) { - _validator.ValidateMageDtoFilter(filter); - return _mapper.MapMageEntityCollectionToMageDtoCollection(await _mageRepository.GetAllMageAsync(_mapper.MapMageDtoFilterToMageFilter(filter))); + var entities = await _mageRepository.GetAllMageAsync(_mapper.Map(filter)); + return _mapper.Map>(entities); } - public async Task GetMageByIdAsync(Guid id) + public async Task? GetMageByIdAsync(Guid id) { - _validator.ValidateGuid(id); - return _mapper.mapMageEntityToMageDto(await _mageRepository.GetMageByIdAsync(id)); + if (id == Guid.Empty) + { + throw new ArgumentNullException("The id is null"); + } + var alreadyExistingMage = await GetAllMageAsync(new MageDtoFilter { Id = id }); + if (!alreadyExistingMage.Any()) + { + throw new NotFoundException("This mage does not exists"); + } + var mage = await _mageRepository.GetMageByIdAsync(id); + return _mapper.Map(mage); } - public Task UpdateMageAsync(MageDtoUpdate dto) + public async Task UpdateMageAsync(MageDtoUpdate dto) { - _validator.ValidateMageDtoUpdate(dto); - return _mageRepository.UpdateMageAsync(_mapper.MapMageDtoUpdateToMageEntity(dto)); + if (dto == null) + { + throw new ArgumentNullException("The DTO received is null"); + } + var alreadyExistingMage = await GetAllMageAsync(new MageDtoFilter { Name = dto.Name, Rank = dto.Rank, Specialisation = dto.Specialisation }); + if (!alreadyExistingMage.Any()) + { + throw new NotFoundException("This mage does not exists"); + } + return await _mageRepository.UpdateMageAsync(_mapper.Map(dto)); } } } diff --git a/Liber_Incantamentum.Application/Services/Generals/SpellService.cs b/Liber_Incantamentum.Application/Services/Generals/SpellService.cs index 2bcc43e..05e8b71 100644 --- a/Liber_Incantamentum.Application/Services/Generals/SpellService.cs +++ b/Liber_Incantamentum.Application/Services/Generals/SpellService.cs @@ -1,51 +1,83 @@ -using Liber_Incantamentum.Application.DTOs.Mage; +using AutoMapper; using Liber_Incantamentum.Application.DTOs.Spell; -using Liber_Incantamentum.Application.Interfaces.Generals; -using Liber_Incantamentum.Application.Interfaces.Mappings; -using Liber_Incantamentum.Application.Interfaces.Validations; +using Liber_Incantamentum.Application.Exceptions; +using Liber_Incantamentum.Application.Interfaces; +using Liber_Incantamentum.Domain.Entities; +using Liber_Incantamentum.Domain.Filter; using Liber_Incantamentum.Domain.Repositories; namespace Liber_Incantamentum.Application.Services.Generals { public class SpellService : ISpellService { - private IValidator _validator; - private ISpellRepository _spellRepository; - private IMapper _mapper; - public SpellService(IValidator validator, ISpellRepository spellRepository, IMapper mapper) + private readonly ISpellRepository _spellRepository; + private readonly IMapper _mapper; + public SpellService(ISpellRepository spellRepository, IMapper mapper) { - _mapper = mapper; - _validator = validator; _spellRepository = spellRepository; + _mapper = mapper; } public async Task AddSpellAsync(SpellDtoCreate dto) { - _validator.ValidateSpellDtoCreate(dto); - return await _spellRepository.AddSpellAsync(_mapper.MapSpellDtoCreateToSpellEntity(dto)); + if (dto == null) + { + throw new ArgumentNullException("The DTO received is null"); + } + var alreadyExistingSpell = await GetAllSpellAsync(new SpellDtoFilter { Name = dto.Name, Description = dto.Description, Type = dto.Type, CreationDate = dto.CreationDate, MageId = dto.MageId }); + if (alreadyExistingSpell.Any()) + { + throw new AlreadyExistingException("This mage does already exists"); + } + return await _spellRepository.AddSpellAsync(_mapper.Map(dto)); } public async Task DeleteSpellAsync(Guid id) { - _validator.ValidateGuid(id); + if (id == Guid.Empty) + { + throw new ArgumentNullException("The id is null"); + } + var alreadyExistingSpell = await GetAllSpellAsync(new SpellDtoFilter { Id = id }); + if (!alreadyExistingSpell.Any()) + { + throw new AlreadyExistingException("This mage does not exists"); + } return await _spellRepository.DeleteSpellAsync(id); } - public async Task?> GetAllSpellAsync(SpellDtoFilter filter) + public async Task> GetAllSpellAsync(SpellDtoFilter filter) { - _validator.ValidateSpellDtoFilter(filter); - return _mapper.MapSpellEntityCollectionToSpellDtoCollection(await _spellRepository.GetAllSpellAsync(_mapper.MapSpellDtoFilterToSpellFilter(filter))); + var entities = await _spellRepository.GetAllSpellAsync(_mapper.Map(filter)); + return _mapper.Map>(entities); } - public async Task GetSpellByIdAsync(Guid id) + public async Task? GetSpellByIdAsync(Guid id) { - _validator.ValidateGuid(id); - return _mapper.mapSpellEntityToSpellDto(await _spellRepository.GetSpellByIdAsync(id)); + if (id == Guid.Empty) + { + throw new ArgumentNullException("The id is null"); + } + var alreadyExistingMage = await GetAllSpellAsync(new SpellDtoFilter { Id = id }); + if (!alreadyExistingMage.Any()) + { + throw new NotFoundException("This mage does not exists"); + } + var mage = await _spellRepository.GetSpellByIdAsync(id); + return _mapper.Map(mage); } - public Task UpdateSpellAsync(SpellDtoUpdate dto) + public async Task UpdateSpellAsync(SpellDtoUpdate dto) { - _validator.ValidateSpellDtoUpdate(dto); - return _spellRepository.UpdateSpellAsync(_mapper.MapSpellDtoUpdateToSpellEntity(dto)); + if (dto == null) + { + throw new ArgumentNullException("The DTO received is null"); + } + var alreadyExistingSpell = await GetAllSpellAsync(new SpellDtoFilter { Id = dto.Id, Name = dto.Name, Description = dto.Description, Type = dto.Type, CreationDate = dto.CreationDate, MageId = dto.MageId }); + if (!alreadyExistingSpell.Any()) + { + throw new NotFoundException("This mage does not exists"); + } + return await _spellRepository.UpdateSpellAsync(_mapper.Map(dto)); } } } diff --git a/Liber_Incantamentum.Application/Services/Mappings/MageMappingProfile.cs b/Liber_Incantamentum.Application/Services/Mappings/MageMappingProfile.cs new file mode 100644 index 0000000..457db78 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Mappings/MageMappingProfile.cs @@ -0,0 +1,30 @@ +using AutoMapper; +using Liber_Incantamentum.Application.DTOs.Mage; +using Liber_Incantamentum.Domain.Entities; +using Liber_Incantamentum.Domain.Filter; + +namespace Liber_Incantamentum.Application.Services.Mappings +{ + public class MageMappingProfile : Profile + { + public MageMappingProfile() + { + CreateMap() + .ForMember(dest => dest.Id, opt => opt.Ignore()) + .ForMember(dest => dest.Spells, opt => opt.Ignore()) + .ReverseMap(); + + CreateMap() + .ForMember(dest => dest.Id, opt => opt.Ignore()) + .ReverseMap(); + + CreateMap() + .ReverseMap(); + + CreateMap() + .ForMember(dest => dest.Id, opt => opt.Ignore()) + .ReverseMap(); + + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Mappings/Mapper.cs b/Liber_Incantamentum.Application/Services/Mappings/Mapper.cs deleted file mode 100644 index 3db232e..0000000 --- a/Liber_Incantamentum.Application/Services/Mappings/Mapper.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Liber_Incantamentum.Application.DTOs.Mage; -using Liber_Incantamentum.Application.DTOs.Spell; -using Liber_Incantamentum.Application.Interfaces.Mappings; -using Liber_Incantamentum.Domain.Entities; -using Liber_Incantamentum.Domain.Filter; - -namespace Liber_Incantamentum.Application.Services.Mappings -{ - public class Mapper : IMapper - { - public Mage MapMageDtoCreateToMageEntity(MageDtoCreate value) - { - return new Mage() - { - Name = value.Name, - Rank = value.Rank, - Specialisation = value.Specialisation - }; - } - - public MageFilter MapMageDtoFilterToMageFilter(MageDtoFilter value) - { - return new MageFilter() - { - Id = value.Id, - Name = value.Name, - Rank = value.Rank, - Specialisation = value.Specialisation - }; - } - - public Mage MapMageDtoUpdateToMageEntity(MageDtoUpdate value) - { - return new Mage() - { - Name = value.Name, - Rank = value.Rank, - Specialisation = value.Specialisation - }; - } - - public ICollection? MapMageEntityCollectionToMageDtoCollection(ICollection? value) - { - var mageDtoCollection = new List(); - foreach (var entity in value) - { - MageDto dto = new MageDto() - { - Id = entity.Id, - Name = entity.Name, - Rank = entity.Rank, - Specialisation = entity.Specialisation - }; - - mageDtoCollection.Add(dto); - } - - return mageDtoCollection; - } - - public MageDto mapMageEntityToMageDto(Mage mage) - { - return new MageDto() - { - Id = mage.Id, - Name = mage.Name, - Rank = mage.Rank, - Specialisation = mage.Specialisation - }; - } - - public Spell MapSpellDtoCreateToSpellEntity(SpellDtoCreate value) - { - return new Spell() - { - Name = value.Name, - Description = value.Description, - Type = value.Type, - CreationDate = value.CreationDate, - MageId = value.MageId - }; - } - - public SpellFilter MapSpellDtoFilterToSpellFilter(SpellDtoFilter value) - { - return new SpellFilter() - { - Id = value.Id, - Name = value.Name, - Description = value.Description, - Type = value.Type, - CreationDate = value.CreationDate, - MageId = value.MageId - }; - } - - public Spell MapSpellDtoUpdateToSpellEntity(SpellDtoUpdate value) - { - return new Spell() - { - Name = value.Name, - Description = value.Description, - Type = value.Type, - CreationDate = value.CreationDate, - MageId = value.MageId - }; - } - - public ICollection? MapSpellEntityCollectionToSpellDtoCollection(ICollection? value) - { - var spellDtoCollection = new List(); - foreach (var x in value) - { - var dto = new SpellDto() - { - Id = x.Id, - Name = x.Name, - Description = x.Description, - Type = x.Type, - CreationDate = x.CreationDate, - MageId = x.MageId - }; - spellDtoCollection.Add(dto); - } - return spellDtoCollection; - } - - public SpellDto mapSpellEntityToSpellDto(Spell spell) - { - return new SpellDto() - { - Id = spell.Id, - Name = spell.Name, - Description = spell.Description, - Type = spell.Type, - CreationDate = spell.CreationDate, - MageId = spell.MageId - }; - } - } -} diff --git a/Liber_Incantamentum.Application/Services/Mappings/SpellMappingProfile.cs b/Liber_Incantamentum.Application/Services/Mappings/SpellMappingProfile.cs new file mode 100644 index 0000000..4a72022 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Mappings/SpellMappingProfile.cs @@ -0,0 +1,29 @@ +using AutoMapper; +using Liber_Incantamentum.Application.DTOs.Spell; +using Liber_Incantamentum.Domain.Entities; +using Liber_Incantamentum.Domain.Filter; + +namespace Liber_Incantamentum.Application.Services.Mappings +{ + public class SpellMappingProfile : Profile + { + public SpellMappingProfile() + { + CreateMap() + .ForMember(x => x.Id, x => x.Ignore()) + .ReverseMap(); + + CreateMap() + .ForMember(x => x.Id, x => x.Ignore()) + .ReverseMap(); + + CreateMap() + .ReverseMap(); + + CreateMap() + .ForMember(x => x.Id, x => x.Ignore()) + .ReverseMap(); + } + } +} + diff --git a/Liber_Incantamentum.Application/Services/Validations/MageDtoCreateValidator.cs b/Liber_Incantamentum.Application/Services/Validations/MageDtoCreateValidator.cs new file mode 100644 index 0000000..8f63f9c --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/MageDtoCreateValidator.cs @@ -0,0 +1,18 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Mage; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class MageDtoCreateValidator : AbstractValidator + { + public MageDtoCreateValidator() + { + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The name is required"); + RuleFor(m => m.Rank) + .NotEmpty().WithMessage("The Rank is required"); + RuleFor(m => m.Specialisation) + .NotEmpty().WithMessage("The specialisation is required"); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/MageDtoFilterValidator.cs b/Liber_Incantamentum.Application/Services/Validations/MageDtoFilterValidator.cs new file mode 100644 index 0000000..cbf5a97 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/MageDtoFilterValidator.cs @@ -0,0 +1,32 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Mage; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class MageDtoFilterValidator : AbstractValidator + { + public MageDtoFilterValidator() + { + When(m => m.Id.HasValue, () => + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The id cannot be empty if provided"); + }); + When(m => !string.IsNullOrEmpty(m.Name), () => + { + RuleFor(m => m.Name) + .MinimumLength(2).WithMessage("Name must be at least 2 characters."); + }); + When(m => !string.IsNullOrEmpty(m.Rank), () => + { + RuleFor(m => m.Rank) + .MinimumLength(2).WithMessage("Name must be at least 2 characters."); + }); + When(m => !string.IsNullOrEmpty(m.Specialisation), () => + { + RuleFor(m => m.Specialisation) + .MinimumLength(2).WithMessage("Name must be at least 2 characters."); + }); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/MageDtoUpdateValidator.cs b/Liber_Incantamentum.Application/Services/Validations/MageDtoUpdateValidator.cs new file mode 100644 index 0000000..4225257 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/MageDtoUpdateValidator.cs @@ -0,0 +1,20 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Mage; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class MageDtoUpdateValidator : AbstractValidator + { + public MageDtoUpdateValidator() + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The Id is required"); + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The Name is required"); + RuleFor(m => m.Rank) + .NotEmpty().WithMessage("The Rank is required"); + RuleFor(m => m.Specialisation) + .NotEmpty().WithMessage("The Specialisation is required"); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/MageDtoValidator.cs b/Liber_Incantamentum.Application/Services/Validations/MageDtoValidator.cs new file mode 100644 index 0000000..a00aea4 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/MageDtoValidator.cs @@ -0,0 +1,30 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Mage; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class MageDtoValidator : AbstractValidator + { + public MageDtoValidator() + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The Id is required"); + + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The Name is required"); + + RuleFor(m => m.Rank) + .NotEmpty().WithMessage("The Rank is required"); + + RuleFor(m => m.Specialisation) + .NotEmpty().WithMessage("The Specialisation is required"); + + RuleFor(m => m.Spells) + .NotNull().WithMessage("Spell collection is required") + .NotEmpty().WithMessage("At least one spell is required"); + + RuleForEach(m => m.Spells) + .SetValidator(new SpellDtoValidator()); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/SpellDtoCreateValidator.cs b/Liber_Incantamentum.Application/Services/Validations/SpellDtoCreateValidator.cs new file mode 100644 index 0000000..a27432c --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/SpellDtoCreateValidator.cs @@ -0,0 +1,22 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class SpellDtoCreateValidator : AbstractValidator + { + public SpellDtoCreateValidator() + { + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The Name is required"); + RuleFor(m => m.Description) + .NotEmpty().WithMessage("The description is required"); + RuleFor(m => m.Type) + .NotEmpty().WithMessage("The type is required"); + RuleFor(m => m.CreationDate) + .LessThanOrEqualTo(DateTime.UtcNow); + RuleFor(m => m.MageId) + .NotEmpty().WithMessage("The mage id is required"); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/SpellDtoFilterValidator.cs b/Liber_Incantamentum.Application/Services/Validations/SpellDtoFilterValidator.cs new file mode 100644 index 0000000..227d0d4 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/SpellDtoFilterValidator.cs @@ -0,0 +1,22 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class SpellDtoFilterValidator : AbstractValidator + { + public SpellDtoFilterValidator() + { + When(m => m.Id.HasValue, () => + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The id cannot be empty if provided"); + }); + When(m => !string.IsNullOrEmpty(m.Name), () => + { + RuleFor(m => m.Name) + .MinimumLength(2).WithMessage("Name must be at least 2 characters."); + }); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/SpellDtoUpdateValidator.cs b/Liber_Incantamentum.Application/Services/Validations/SpellDtoUpdateValidator.cs new file mode 100644 index 0000000..ebc4598 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/SpellDtoUpdateValidator.cs @@ -0,0 +1,24 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class SpellDtoUpdateValidator : AbstractValidator + { + public SpellDtoUpdateValidator() + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The Id cannot be empty"); + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The Name cannot be empty"); + RuleFor(m => m.Description) + .NotEmpty().WithMessage("The Description cannot be empty"); + RuleFor(m => m.Type) + .NotEmpty().WithMessage("The Type cannot be empty"); + RuleFor(m => m.CreationDate) + .LessThanOrEqualTo(DateTime.UtcNow); + RuleFor(m => m.MageId) + .NotEmpty().WithMessage("The mage id cannot be empty"); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/SpellDtoValidator.cs b/Liber_Incantamentum.Application/Services/Validations/SpellDtoValidator.cs new file mode 100644 index 0000000..2a3c380 --- /dev/null +++ b/Liber_Incantamentum.Application/Services/Validations/SpellDtoValidator.cs @@ -0,0 +1,24 @@ +using FluentValidation; +using Liber_Incantamentum.Application.DTOs.Spell; + +namespace Liber_Incantamentum.Application.Services.Validations +{ + public class SpellDtoValidator : AbstractValidator + { + public SpellDtoValidator() + { + RuleFor(m => m.Id) + .NotEmpty().WithMessage("The Id cannot be empty"); + RuleFor(m => m.Name) + .NotEmpty().WithMessage("The Name cannot be empty"); + RuleFor(m => m.Description) + .NotEmpty().WithMessage("The Description cannot be empty"); + RuleFor(m => m.Type) + .NotEmpty().WithMessage("The Type cannot be empty"); + RuleFor(m => m.CreationDate) + .LessThanOrEqualTo(DateTime.UtcNow); + RuleFor(m => m.MageId) + .NotEmpty().WithMessage("The mage id cannot be empty"); + } + } +} diff --git a/Liber_Incantamentum.Application/Services/Validations/Validator.cs b/Liber_Incantamentum.Application/Services/Validations/Validator.cs deleted file mode 100644 index fb03a5b..0000000 --- a/Liber_Incantamentum.Application/Services/Validations/Validator.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Liber_Incantamentum.Application.Interfaces.Validations; - -namespace Liber_Incantamentum.Application.Services.Validations -{ - public class Validator : IValidator - { - } -} diff --git a/Liber_Incantamentum.Domain/Entities/Mage.cs b/Liber_Incantamentum.Domain/Entities/Mage.cs index 04c94a6..36cd73d 100644 --- a/Liber_Incantamentum.Domain/Entities/Mage.cs +++ b/Liber_Incantamentum.Domain/Entities/Mage.cs @@ -3,6 +3,10 @@ public class Mage { public Guid Id { get; private set; } + public Mage() + { + Id = Guid.NewGuid(); + } public required string Name { get; set; } public required string Rank { get; set; } public required string Specialisation { get; set; } diff --git a/Liber_Incantamentum.Domain/Entities/Spell.cs b/Liber_Incantamentum.Domain/Entities/Spell.cs index e5be4e3..7539e97 100644 --- a/Liber_Incantamentum.Domain/Entities/Spell.cs +++ b/Liber_Incantamentum.Domain/Entities/Spell.cs @@ -3,6 +3,10 @@ public class Spell { public Guid Id { get; private set; } + public Spell() + { + Id = Guid.NewGuid(); + } public required string Name { get; set; } public required string Description { get; set; } public required string Type { get; set; } diff --git a/Liber_Incantamentum/Liber_Incantamentum.API.csproj b/Liber_Incantamentum/Liber_Incantamentum.API.csproj index 4f288b8..646c96b 100644 --- a/Liber_Incantamentum/Liber_Incantamentum.API.csproj +++ b/Liber_Incantamentum/Liber_Incantamentum.API.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -18,7 +18,14 @@ + + + + + + + diff --git a/Liber_Incantamentum/Program.cs b/Liber_Incantamentum/Program.cs index 666a9c5..f034c11 100644 --- a/Liber_Incantamentum/Program.cs +++ b/Liber_Incantamentum/Program.cs @@ -1,3 +1,10 @@ +using FluentValidation; +using AutoMapper; +using Liber_Incantamentum.Application.Services.Mappings; +using Liber_Incantamentum.Application.Services.Validations; + + + var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -6,6 +13,10 @@ builder.Services.AddControllers(); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); +builder.Services.AddValidatorsFromAssemblyContaining(); + +builder.Services.AddAutoMapper(cfg => { }, typeof(MageMappingProfile).Assembly); + var app = builder.Build(); // Configure the HTTP request pipeline.