Commit 5e219566 authored by hasan khaddour's avatar hasan khaddour

refactor result pattern

parent 69af1fba
using AutoMapper; using AutoMapper;
using PSManagement.Application.Customers.Common; using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.Entities; using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.ValueObjects; using PSManagement.Domain.Customers.ValueObjects;
using System; using System;
......
using FluentResults; using Ardalis.Result;
using FluentValidation; using FluentValidation;
using MediatR; using MediatR;
...@@ -13,7 +13,7 @@ namespace PSManagement.Application.Behaviors.ValidationBehavior ...@@ -13,7 +13,7 @@ namespace PSManagement.Application.Behaviors.ValidationBehavior
{ {
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse> where TResponse : ResultBase where TRequest : IRequest<TResponse>
{ {
private readonly IEnumerable<IValidator<TRequest>> _validators; private readonly IEnumerable<IValidator<TRequest>> _validators;
...@@ -23,29 +23,50 @@ namespace PSManagement.Application.Behaviors.ValidationBehavior ...@@ -23,29 +23,50 @@ namespace PSManagement.Application.Behaviors.ValidationBehavior
} }
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next) public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{ {
var context = new ValidationContext<TRequest>(request);
if (_validators is null) { if (_validators is null) {
return await next(); return await next();
} }
var validationTasks = _validators.Select(v => v.ValidateAsync(request, cancellationToken));
var validationResults = await Task.WhenAll(validationTasks);
var errors = validationResults.SelectMany(r => r.Errors)
.Where(e => e != null)
.Select(e => new ValidationError(e.ErrorCode,e.ErrorMessage,e.ErrorCode,new ValidationSeverity()))
.ToList();
if (errors.Any())
{
return (dynamic)Result.Invalid(errors);
}
return await next();
}
private Result ValidateAsync(TRequest request)
{
var context = new ValidationContext<TRequest>(request);
var failures = _validators var failures = _validators
.Select(v => v.Validate(context)) .Select(v => v.Validate(context))
.SelectMany(result => result.Errors) .SelectMany(result => result.Errors)
.Where(f => f != null) .Where(f => f != null)
.ToList(); .ToList();
if (failures.Count != 0) if (failures.Count != 0)
{ {
var result =Result.Fail("validation Error.");
foreach (var failure in failures) var result = Result.Invalid(new ValidationError("validation Error."));
{ //foreach (var failure in failures)
result.Reasons.Add(new Error(failure.ErrorMessage)); //{
} // result.Reasons.Add(new Error(failure.ErrorMessage));
return (dynamic)result; //}
return result;
} }
return await next(); return Result.Success();
} }
} }
} }
 
using FluentResults; using Ardalis.Result;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
......
using FluentResults; using Ardalis.Result;
using PSManagement.Domain.Identity.Entities; using PSManagement.Domain.Identity.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
......
using FluentResults; using Ardalis.Result;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -7,10 +7,9 @@ namespace PSManagement.Application.Contracts.Authorization ...@@ -7,10 +7,9 @@ namespace PSManagement.Application.Contracts.Authorization
{ {
public interface IUserRoleService public interface IUserRoleService
{ {
Task<bool> IsInRoleAsync(int userId, string role); Task<bool> IsInRoleAsync(int userId, string roleName);
Task<List<string>> GetUserRolesAsync(string email); Task<Result<List<string>>> GetUserRolesAsync(string email);
Task<Result> AssignUserToRole(string userName, string roleName); Task<Result> AssignUserToRole(string email, string roleName);
Task UpdateUsersRole(string userName, string usersRole);
Task<Result> RemoveUserFromRole(string email, string roleName); Task<Result> RemoveUserFromRole(string email, string roleName);
} }
......
using PSManagement.Domain.Employees.Entities; using PSManagement.Domain.Employees.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace PSManagement.Application.Contracts.Providers namespace PSManagement.Application.Contracts.Providers
{ {
public interface IDepartmentsProvider public interface IDepartmentsProvider
{ {
public ICollection<Department> FetchDepartments(); public Task<ICollection<Department>> FetchDepartments();
} }
} }
...@@ -9,6 +9,6 @@ namespace PSManagement.Application.Contracts.Providers ...@@ -9,6 +9,6 @@ namespace PSManagement.Application.Contracts.Providers
{ {
public interface IEmployeesProvider public interface IEmployeesProvider
{ {
public ICollection<Employee> FetchEmployees(); public Task<IEnumerable<Employee>> FetchEmployees();
} }
} }
using FluentResults; using Ardalis.Result;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
......
using PSManagement.Application.Contracts.Providers;
using System.Threading.Tasks;
namespace PSManagement.Application.Contracts.SyncData
{
public interface ISyncDepartmentsService
{
public Task<SyncResponse> SyncEmployees(IEmployeesProvider employeesProvider);
}
}
...@@ -9,10 +9,10 @@ namespace PSManagement.Application.Contracts.SyncData ...@@ -9,10 +9,10 @@ namespace PSManagement.Application.Contracts.SyncData
{ {
public interface ISyncEmployeesService public interface ISyncEmployeesService
{ {
public void SyncEmployees(IEmployeesProvider employeesProvider); public Task<SyncResponse> SyncEmployees(IEmployeesProvider employeesProvider);
}
public interface ISyncDepartmentsService
{
public void SyncEmployees(IEmployeesProvider employeesProvider);
} }
public record SyncResponse(
int SyncDataCount,
DateTime SyncDate
);
} }
using PSManagement.Domain.Identity.Entities; using PSManagement.Domain.Identity.Entities;
using System; using System;
namespace PSManagement.Application.Contracts.Authorization namespace PSManagement.Application.Contracts.Tokens
{ {
public interface IJwtTokenGenerator public interface IJwtTokenGenerator
{ {
public String GenerateToken(User user); public string GenerateToken(User user);
} }
} }
...@@ -11,11 +11,12 @@ namespace PSManagement.Application.Customers.Events ...@@ -11,11 +11,12 @@ namespace PSManagement.Application.Customers.Events
{ {
public class CustomerCreatedEventHandler : IDomainEventHandler<CutsomerCreatedEvent> public class CustomerCreatedEventHandler : IDomainEventHandler<CutsomerCreatedEvent>
{ {
public async Task Handle(CutsomerCreatedEvent notification, CancellationToken cancellationToken) public Task Handle(CutsomerCreatedEvent notification, CancellationToken cancellationToken)
{ {
Console.WriteLine("fdgfg"); Console.WriteLine("fdgfg");
return Task.CompletedTask;
} }
} }
} }
using FluentResults; using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Repositories; using PSManagement.SharedKernel.Repositories;
using System; using System;
...@@ -8,6 +8,9 @@ using System.Text; ...@@ -8,6 +8,9 @@ using System.Text;
namespace PSManagement.Application.Customers.UseCases.Commands.AddContactInfo namespace PSManagement.Application.Customers.UseCases.Commands.AddContactInfo
{ {
public record AddContactInfoCommand(int CustomerId,String ContactType,String ContactValue ) : ICommand<Result>; public record AddContactInfoCommand(
int CustomerId,
String ContactType,
String ContactValue ) : ICommand<Result>;
} }
using FluentResults; using Ardalis.Result;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainErrors; using PSManagement.Domain.Customers.DomainErrors;
using PSManagement.Domain.Customers.Entities; using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
...@@ -24,13 +23,13 @@ namespace PSManagement.Application.Customers.UseCases.Commands.AddContactInfo ...@@ -24,13 +23,13 @@ namespace PSManagement.Application.Customers.UseCases.Commands.AddContactInfo
if (customer is null) { if (customer is null) {
return Result.Fail(CustomerErrors.InvalidEntryError); return Result.Invalid(CustomerErrors.InvalidEntryError);
} }
ContactInfo contact = new (request.ContactValue,request.ContactType); ContactInfo contact = new (request.ContactValue,request.ContactType);
customer.AddContactInfo(contact); customer.AddContactInfo(contact);
await _customersRepository.UpdateAsync(customer); await _customersRepository.UpdateAsync(customer);
return Result.Ok(); return Result.Success();
} }
} }
......
 
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.ValueObjects; using PSManagement.Domain.Customers.ValueObjects;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using System; using System;
......
using AutoMapper; using Ardalis.Result;
using FluentResults; using AutoMapper;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainEvents; using PSManagement.Domain.Customers.DomainEvents;
using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
using PSManagement.Domain.Customers.ValueObjects; using PSManagement.Domain.Customers.ValueObjects;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
...@@ -35,7 +35,7 @@ namespace PSManagement.Application.Customers.UseCases.Commands.CreateCustomer ...@@ -35,7 +35,7 @@ namespace PSManagement.Application.Customers.UseCases.Commands.CreateCustomer
customer.AddDomainEvent(new CutsomerCreatedEvent(customer.Id ,customer.CustomerName)); customer.AddDomainEvent(new CutsomerCreatedEvent(customer.Id ,customer.CustomerName));
await _unitOfWork.SaveChangesAsync(); await _unitOfWork.SaveChangesAsync();
return Result.Ok(customer.Id); return Result.Success(customer.Id);
} }
} }
} }
using FluentResults; 
using Ardalis.Result;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
......
using FluentResults; using Ardalis.Result;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainErrors; using PSManagement.Domain.Customers.DomainErrors;
using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using System; using System;
...@@ -27,12 +27,12 @@ namespace PSManagement.Application.Customers.UseCases.Commands.DeleteCustomer ...@@ -27,12 +27,12 @@ namespace PSManagement.Application.Customers.UseCases.Commands.DeleteCustomer
if (customer is null) if (customer is null)
{ {
return Result.Fail(CustomerErrors.InvalidEntryError); return Result.Invalid(CustomerErrors.InvalidEntryError);
} }
await _customersRepository.DeleteAsync(customer); await _customersRepository.DeleteAsync(customer);
return Result.Ok(); return Result.Success();
} }
} }
} }
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.ValueObjects; using PSManagement.Domain.Customers.ValueObjects;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using System; using System;
......
using AutoMapper; using Ardalis.Result;
using FluentResults; using AutoMapper;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainEvents; using PSManagement.Domain.Customers.DomainEvents;
using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
using PSManagement.Domain.Customers.ValueObjects; using PSManagement.Domain.Customers.ValueObjects;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
...@@ -31,7 +32,7 @@ namespace PSManagement.Application.Customers.UseCases.Commands.UpdateCustomer ...@@ -31,7 +32,7 @@ namespace PSManagement.Application.Customers.UseCases.Commands.UpdateCustomer
await _customerRepository.UpdateAsync(customer); await _customerRepository.UpdateAsync(customer);
return Result.Ok(); return Result.Success();
} }
} }
} }
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Customers.Common; using PSManagement.Application.Customers.Common;
using PSManagement.SharedKernel.CQRS.Query; using PSManagement.SharedKernel.CQRS.Query;
using System; using System;
......
using AutoMapper; using Ardalis.Result;
using FluentResults; using AutoMapper;
using PSManagement.Application.Customers.Common; using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Aggregate;
using PSManagement.Domain.Customers.DomainErrors; using PSManagement.Domain.Customers.DomainErrors;
using PSManagement.Domain.Customers.Entities;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
using PSManagement.SharedKernel.CQRS.Query; using PSManagement.SharedKernel.CQRS.Query;
using System.Collections.Generic; using System.Collections.Generic;
...@@ -25,9 +25,9 @@ namespace PSManagement.Application.Customers.UseCases.Queries.GetCustomer ...@@ -25,9 +25,9 @@ namespace PSManagement.Application.Customers.UseCases.Queries.GetCustomer
{ {
Customer customer = await _customersRepository.GetByIdAsync(request.customerId); Customer customer = await _customersRepository.GetByIdAsync(request.customerId);
if (customer is null) { if (customer is null) {
return Result.Fail(CustomerErrors.InvalidEntryError); return Result.NotFound(CustomerErrors.InvalidEntryError.ErrorMessage);
} }
return Result.Ok(_mapper.Map<CustomerDTO>(customer)); return Result.Success(_mapper.Map<CustomerDTO>(customer));
} }
} }
......
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Customers.Common; using PSManagement.Application.Customers.Common;
using PSManagement.SharedKernel.CQRS.Query; using PSManagement.SharedKernel.CQRS.Query;
using System; using System;
......
using AutoMapper; using Ardalis.Result;
using FluentResults; using AutoMapper;
using PSManagement.Application.Customers.Common; using PSManagement.Application.Customers.Common;
using PSManagement.Domain.Customers.Repositories; using PSManagement.Domain.Customers.Repositories;
using PSManagement.SharedKernel.CQRS.Query; using PSManagement.SharedKernel.CQRS.Query;
...@@ -21,7 +21,7 @@ namespace PSManagement.Application.Customers.UseCases.Queries.ListAllCustomers ...@@ -21,7 +21,7 @@ namespace PSManagement.Application.Customers.UseCases.Queries.ListAllCustomers
public async Task<Result<IEnumerable<CustomerDTO>>> Handle(ListAllCustomersQuery request, CancellationToken cancellationToken) public async Task<Result<IEnumerable<CustomerDTO>>> Handle(ListAllCustomersQuery request, CancellationToken cancellationToken)
{ {
return Result.Ok( _mapper.Map<IEnumerable<CustomerDTO>>(await _customersRepository.ListAsync())); return Result.Success( _mapper.Map<IEnumerable<CustomerDTO>>(await _customersRepository.ListAsync()));
} }
} }
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<NoWarn>NU1701</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Behaviors\AuthorizationBehavior\" /> <Folder Include="Behaviors\AuthorizationBehavior\" />
<Folder Include="Employees\UseCases\Commands\UpdateEmployeeWorkHours\" /> <Folder Include="Employees\UseCases\Commands\UpdateEmployeeWorkHours\" />
<Folder Include="Employees\UseCases\Commands\SyncEmployeesData\" />
<Folder Include="Employees\UseCases\Queries\GetEmployeeWorkingHours\" /> <Folder Include="Employees\UseCases\Queries\GetEmployeeWorkingHours\" />
<Folder Include="Employees\UseCases\Queries\GetEmployeeProjects\" /> <Folder Include="Employees\UseCases\Queries\GetEmployeeProjects\" />
<Folder Include="Employees\UseCases\Queries\GetAvailableEmployees\" /> <Folder Include="Employees\UseCases\Queries\GetAvailableEmployees\" />
...@@ -58,6 +60,7 @@ ...@@ -58,6 +60,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="7.0.1" /> <PackageReference Include="AutoMapper" Version="7.0.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="5.0.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="5.0.1" />
<PackageReference Include="ErrorOr" Version="2.0.1" />
<PackageReference Include="FluentValidation" Version="8.6.3" /> <PackageReference Include="FluentValidation" Version="8.6.3" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="8.6.3" /> <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="8.6.3" />
<PackageReference Include="MediatR" Version="8.0.1" /> <PackageReference Include="MediatR" Version="8.0.1" />
......
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Projects.Common; using PSManagement.Application.Projects.Common;
using PSManagement.Domain.Projects.ValueObjects; using PSManagement.Domain.Projects.ValueObjects;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
...@@ -13,9 +13,10 @@ namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject ...@@ -13,9 +13,10 @@ namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
ProjectInfo ProjectInfo , ProjectInfo ProjectInfo ,
ProposalInfo ProposalInfo, ProposalInfo ProposalInfo,
Aggreement ProjectAggreement, Aggreement ProjectAggreement,
FinancialFund FinancialFund,
int TeamLeaderId , int TeamLeaderId ,
int ProjectManagerId, int ProjectManagerId,
int ProposerId int ProposerId,
) : ICommand<Result<ProjectDTO>>; int ExecuterId
) : ICommand<Result<CreateProjectResponse>>;
} }
using FluentResults; using Ardalis.Result;
using PSManagement.Application.Projects.Common; using PSManagement.Application.Projects.Common;
using PSManagement.Domain.Projects.Builders;
using PSManagement.Domain.Projects.Entities;
using PSManagement.Domain.Projects.Repositories; using PSManagement.Domain.Projects.Repositories;
using PSManagement.SharedKernel.CQRS.Command; using PSManagement.SharedKernel.CQRS.Command;
using PSManagement.SharedKernel.Interfaces;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
{ {
public class CreateProjectCommandHandler : ICommandHandler<CreateProjectCommand, Result<ProjectDTO>> public class CreateProjectCommandHandler : ICommandHandler<CreateProjectCommand, Result<CreateProjectResponse>>
{ {
private readonly IProjectsRepository _projectsRepository; private readonly IProjectsRepository _projectsRepository;
private readonly ProjectBuilder _projectBuilder;
private readonly IUnitOfWork _unitOfWork;
public CreateProjectCommandHandler(IProjectsRepository projectsRepository)
public CreateProjectCommandHandler(
IProjectsRepository projectsRepository,
ProjectBuilder projectBuilder,
IUnitOfWork unitOfWork)
{ {
_projectsRepository = projectsRepository; _projectsRepository = projectsRepository;
_projectBuilder = projectBuilder;
_unitOfWork = unitOfWork;
} }
public Task<Result<ProjectDTO>> Handle(CreateProjectCommand request, CancellationToken cancellationToken) public async Task<Result<CreateProjectResponse>> Handle(CreateProjectCommand request, CancellationToken cancellationToken)
{ {
Project project = _projectBuilder
return Task.FromResult<Result<ProjectDTO>>(Result.Fail(new Error(""))); .WithProjectAggreement(request.ProjectAggreement)
.WithProjectInfo(request.ProjectInfo)
.WithProposalInfo(request.ProposalInfo)
.WithExecuter(request.ExecuterId)
.WithFinancialFund(request.FinancialFund)
.WithProjectManager(request.ProjectManagerId)
.WithTeamLeader(request.TeamLeaderId)
.WithProposer(request.ProposerId)
.Build();
Project AddedProject =await _projectsRepository.AddAsync(project);
CreateProjectResponse response = new (
AddedProject.Id,
AddedProject.ProposalInfo,
AddedProject.ProjectInfo,
AddedProject.ProjectAggreement,
AddedProject.TeamLeaderId,
AddedProject.ProjectManagerId,
AddedProject.ExecuterId
);
await _unitOfWork.SaveChangesAsync();
return Result.Success(response);
} }
} }
......
using PSManagement.Domain.Projects.ValueObjects;
namespace PSManagement.Application.Projects.UseCases.Commands.CreateProject
{
public record CreateProjectResponse(
int ProjectId,
ProposalInfo ProposalInfo ,
ProjectInfo ProjectInfo,
Aggreement ProjectAggrement,
int TeamLeaderId ,
int ProjectManagerId,
int ExecuterId
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment