| namespace BlackRock.Reporting.API.Controllers.Dto | |||||
| { | |||||
| public class UserDto | |||||
| { | |||||
| public string? Name { get; set; } | |||||
| public string? Email { get; set; } | |||||
| } | |||||
| } |
| using BlackRock.Reporting.API.Mediator; | using BlackRock.Reporting.API.Mediator; | ||||
| using BlackRock.Reporting.API.Models; | |||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using MediatR; | using MediatR; | ||||
| using Microsoft.AspNetCore.Authorization; | |||||
| using Microsoft.AspNetCore.Mvc; | using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | |||||
| namespace BlackRock.Reporting.API.Controllers | namespace BlackRock.Reporting.API.Controllers | ||||
| { | { | ||||
| // GET: api/users/1 | // GET: api/users/1 | ||||
| [HttpGet] | [HttpGet] | ||||
| [Route("api/users/{id}")] | [Route("api/users/{id}")] | ||||
| public async Task<IActionResult> Get(Guid id) | |||||
| public async Task<IActionResult> GetUser(int id) | |||||
| { | { | ||||
| var result = await mediator.Send(new GetUsersQuery(id)); | var result = await mediator.Send(new GetUsersQuery(id)); | ||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| // GET: api/users?Page=2&PageSize=25 | // GET: api/users?Page=2&PageSize=25 | ||||
| [HttpGet] | [HttpGet] | ||||
| [Route("api/users")] | [Route("api/users")] | ||||
| public async Task<IActionResult> GetAll(UserQuery filter) | |||||
| public async Task<IActionResult> GetAllUsers(GetAllUsersQuery query) | |||||
| { | { | ||||
| var result = await mediator.Send(new GetAllUsersQuery(filter)); | |||||
| var result = await mediator.Send(query); | |||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| return BadRequest(result.Error); | return BadRequest(result.Error); | ||||
| if (result.Data == null) | if (result.Data == null) | ||||
| return NotFound("Id is not valid"); | return NotFound("Id is not valid"); | ||||
| return Ok(result.Data); | return Ok(result.Data); | ||||
| } | } | ||||
| // POST: api/users | // POST: api/users | ||||
| [HttpPost] | [HttpPost] | ||||
| [Route("api/users")] | [Route("api/users")] | ||||
| public async Task<IActionResult> Post([FromBody] UserForm form) | |||||
| public async Task<IActionResult> CreateUser([FromBody] CreateUsersCommand user) | |||||
| { | { | ||||
| if (!ModelState.IsValid) | if (!ModelState.IsValid) | ||||
| return BadRequest(ModelState); | return BadRequest(ModelState); | ||||
| var result = await mediator.Send(new CreateUsersCommand(form)); | |||||
| var result = await mediator.Send(user); | |||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| return BadRequest(result.Error); | return BadRequest(result.Error); | ||||
| // PUT: api/users/1 | // PUT: api/users/1 | ||||
| [HttpPut] | [HttpPut] | ||||
| [Route("api/users/{id}")] | [Route("api/users/{id}")] | ||||
| public async Task<IActionResult> Put(Guid id, [FromBody] UserForm form) | |||||
| public async Task<IActionResult> UpdateAllUser(int id, [FromBody] UserCommand user) | |||||
| { | { | ||||
| if (!ModelState.IsValid) | if (!ModelState.IsValid) | ||||
| return BadRequest(ErrorResponse.Validation(ModelState)); | return BadRequest(ErrorResponse.Validation(ModelState)); | ||||
| var result = await mediator.Send(new UpdateAllUsersCommand(id, form)); | |||||
| var result = await mediator.Send(new UpdateAllUsersCommand(id,user)); | |||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| return BadRequest(result.Error); | return BadRequest(result.Error); | ||||
| // PATCH: api/users/1/email | // PATCH: api/users/1/email | ||||
| [HttpPatch] | [HttpPatch] | ||||
| [Route("api/users/{id}/email")] | [Route("api/users/{id}/email")] | ||||
| public async Task<IActionResult> UpdateEmail(Guid id, [FromBody] UserForm form) | |||||
| public async Task<IActionResult> UpdateUserEmail(int id, [FromBody] UserCommand user) | |||||
| { | { | ||||
| if (!ModelState.IsValid) | if (!ModelState.IsValid) | ||||
| return BadRequest(ErrorResponse.Validation(ModelState)); | return BadRequest(ErrorResponse.Validation(ModelState)); | ||||
| var result = await mediator.Send(new UpdateEmailUsersCommand(id, form)); | |||||
| var result = await mediator.Send(new UpdateEmailUsersCommand(id, user)); | |||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| return BadRequest(result.Error); | return BadRequest(result.Error); | ||||
| // DELETE: api/users/1 | // DELETE: api/users/1 | ||||
| [HttpDelete] | [HttpDelete] | ||||
| [Route("api/users/{id}")] | [Route("api/users/{id}")] | ||||
| public async Task<IActionResult> Delete(Guid id) | |||||
| public async Task<IActionResult> DeleteUser(int id) | |||||
| { | { | ||||
| if (!ModelState.IsValid) | if (!ModelState.IsValid) | ||||
| return BadRequest(ErrorResponse.Validation(ModelState)); | return BadRequest(ErrorResponse.Validation(ModelState)); | ||||
| } | } | ||||
| } | } | ||||
| public class ErrorResponse | |||||
| { | |||||
| public IEnumerable<string> Errors { get; set; } | |||||
| public Enum StatusCode { get; set; } | |||||
| public ModelStateDictionary Validations { get; set; } | |||||
| public static ErrorResponse Validation(ModelStateDictionary validations) | |||||
| { | |||||
| return new ErrorResponse | |||||
| { | |||||
| Validations = validations | |||||
| }; | |||||
| } | |||||
| } | |||||
| // I/O | // I/O | ||||
| // Output: DTO : Entity wraper, Agregations | // Output: DTO : Entity wraper, Agregations | ||||
| // Input: Query / Form | // Input: Query / Form |
| using System.Linq.Expressions; | using System.Linq.Expressions; | ||||
| using BlackRock.Reporting.API.Core.Models; | using BlackRock.Reporting.API.Core.Models; | ||||
| using BlackRock.Reporting.API.Models; | |||||
| using BlackRock.Reporting.API.Persistence; | using BlackRock.Reporting.API.Persistence; | ||||
| namespace BlackRock.Reporting.API.Core | namespace BlackRock.Reporting.API.Core | ||||
| { | { | ||||
| public interface IRepository<TEntity> where TEntity : class | |||||
| public interface IRepository<TEntity> where TEntity : class, IBaseEntity | |||||
| { | { | ||||
| Task<TEntity> GetByIdAsync(Guid id); | |||||
| Task<IQueryable<TEntity>> GetAllAsync(); | |||||
| Task<TEntity> GetByIdAsync(int id); | |||||
| Task<IEnumerable<TEntity>> GetAllAsync(); | |||||
| Task AddAsync(TEntity entity); | Task AddAsync(TEntity entity); | ||||
| Task AddRangeAsync(IEnumerable<TEntity> entities); | Task AddRangeAsync(IEnumerable<TEntity> entities); | ||||
| void Update(TEntity entity); | |||||
| void UpdateRange(IEnumerable<TEntity> entities); | |||||
| void Remove(TEntity entity); | void Remove(TEntity entity); | ||||
| void RemoveRange(IEnumerable<TEntity> entities); | void RemoveRange(IEnumerable<TEntity> entities); | ||||
| } | } |
| { | { | ||||
| public interface IUnitOfWork | public interface IUnitOfWork | ||||
| { | { | ||||
| IUsersRepository UsersRepository{get;set;} | |||||
| Task SaveChangesAsync(); | Task SaveChangesAsync(); | ||||
| } | } | ||||
| } | } |
| using BlackRock.Reporting.API.Mediator; | |||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| namespace BlackRock.Reporting.API.Core | namespace BlackRock.Reporting.API.Core | ||||
| { | { | ||||
| public interface IUsersRepository : IRepository<User> | public interface IUsersRepository : IRepository<User> | ||||
| { | { | ||||
| void UpdateEmail(User user,string email); | |||||
| Task<PaggingCollection<User>> GetAllByFilter(PaggingAndFiltering queryObj); | |||||
| } | } | ||||
| } | } |
| using System.Linq.Expressions; | |||||
| using BlackRock.Reporting.API.Mediator; | |||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| namespace BlackRock.Reporting.API.Extensions | |||||
| { | |||||
| public static class IQueryableExtensions | |||||
| { | |||||
| public static IQueryable<T> ApplyOrdering<T>(this IQueryable<T> query, | |||||
| IPaggingAndFiltering queryObj, Dictionary<string, Expression<Func<T, object>>> columnsMap) | |||||
| { | |||||
| if (string.IsNullOrWhiteSpace(queryObj.SortBy) || | |||||
| !columnsMap.ContainsKey(queryObj.SortBy)) | |||||
| return query; | |||||
| if (queryObj.IsSortAscending) | |||||
| return query.OrderBy(columnsMap[queryObj.SortBy]); | |||||
| return query.OrderByDescending(columnsMap[queryObj.SortBy]); | |||||
| } | |||||
| public static IQueryable<T> ApplyPagging<T>(this IQueryable<T> query, | |||||
| IPaggingAndFiltering queryObj) | |||||
| { | |||||
| if (queryObj.Page <= 0) | |||||
| queryObj.Page = 1; | |||||
| if (queryObj.PageSize <= 0) | |||||
| queryObj.PageSize = 10; | |||||
| return query.Skip((queryObj.Page - 1) * queryObj.PageSize) | |||||
| .Take(queryObj.PageSize); | |||||
| } | |||||
| } | |||||
| } |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| namespace BlackRock.Reporting.API.Mediator | namespace BlackRock.Reporting.API.Mediator | ||||
| { | { | ||||
| public class CreateUsersCommand : IRequest<Result<Guid>> | |||||
| public class CreateUsersCommand : UserCommand, IRequest<Result<int>> | |||||
| { | { | ||||
| public UserForm User { get; } | |||||
| public CreateUsersCommand(UserForm user) | |||||
| public CreateUsersCommand(string Name, string Email) : base(Name, Email) | |||||
| { | { | ||||
| this.User = user; | |||||
| } | } | ||||
| } | } | ||||
| public class CreateUsersCommandHandlers : IRequestHandler<CreateUsersCommand, Result<Guid>> | |||||
| public class CreateUsersCommandHandlers : IRequestHandler<CreateUsersCommand, Result<int>> | |||||
| { | { | ||||
| private readonly ILogger<CreateUsersCommandHandlers> logger; | private readonly ILogger<CreateUsersCommandHandlers> logger; | ||||
| private readonly IMapper mapper; | private readonly IMapper mapper; | ||||
| private readonly IUsersRepository repository; | |||||
| private readonly IUnitOfWork unitOfWork; | private readonly IUnitOfWork unitOfWork; | ||||
| public CreateUsersCommandHandlers(ILogger<CreateUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||||
| public CreateUsersCommandHandlers(ILogger<CreateUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||||
| { | { | ||||
| this.unitOfWork = unitOfWork; | this.unitOfWork = unitOfWork; | ||||
| this.repository = repository; | |||||
| this.mapper = mapper; | this.mapper = mapper; | ||||
| this.logger = logger; | this.logger = logger; | ||||
| } | } | ||||
| public async Task<Result<Guid>> Handle(CreateUsersCommand command, CancellationToken cancellationToken) | |||||
| public async Task<Result<int>> Handle(CreateUsersCommand command, CancellationToken cancellationToken) | |||||
| { | { | ||||
| if (command.User == null) | |||||
| throw new ArgumentException($"Parameter {nameof(command.User)} must not be null"); | |||||
| if (command is null) | |||||
| throw new ArgumentException($"Parameter {nameof(command)} must not be null"); | |||||
| try | try | ||||
| { | { | ||||
| logger.LogInformation("Creating new user ..."); | logger.LogInformation("Creating new user ..."); | ||||
| var user = mapper.Map<UserForm, User>(command.User); | |||||
| user.Id = Guid.NewGuid(); | |||||
| await repository.AddAsync(user); | |||||
| var user = mapper.Map<UserCommand, User>(command); | |||||
| await unitOfWork.UsersRepository.AddAsync(user); | |||||
| await unitOfWork.SaveChangesAsync(); | await unitOfWork.SaveChangesAsync(); | ||||
| logger.LogInformation($"User with id {user.Id} has been created successfully"); | logger.LogInformation($"User with id {user.Id} has been created successfully"); | ||||
| return new Result<Guid> { Data = user.Id }; | |||||
| return new Result<int> { Data = user.Id}; | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| return new Result<Guid> { IsSuccess = false, Error = "Faild to add data to DB." }; | |||||
| logger.LogError(ex,"Faild to add data to DB."); | |||||
| return new Result<int> { IsSuccess = false, Error = "Faild to add data to DB." }; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| namespace BlackRock.Reporting.API.Mediator | namespace BlackRock.Reporting.API.Mediator | ||||
| { | { | ||||
| public class DeleteUsersCommand : IRequest<Result<Guid>> | |||||
| public class DeleteUsersCommand : UserQuery, IRequest<Result<int>> | |||||
| { | { | ||||
| public Guid Id { get; } | |||||
| public DeleteUsersCommand(Guid id) | |||||
| public DeleteUsersCommand(int id) : base(id) | |||||
| { | { | ||||
| this.Id = id; | |||||
| } | } | ||||
| } | } | ||||
| public class DeleteUsersCommandHandlers : IRequestHandler<DeleteUsersCommand, Result<Guid>> | |||||
| public class DeleteUsersCommandHandlers : IRequestHandler<DeleteUsersCommand, Result<int>> | |||||
| { | { | ||||
| private readonly ILogger<DeleteUsersCommandHandlers> logger; | private readonly ILogger<DeleteUsersCommandHandlers> logger; | ||||
| private readonly IMapper mapper; | private readonly IMapper mapper; | ||||
| private readonly IUsersRepository repository; | |||||
| private readonly IUnitOfWork unitOfWork; | private readonly IUnitOfWork unitOfWork; | ||||
| public DeleteUsersCommandHandlers(ILogger<DeleteUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||||
| public DeleteUsersCommandHandlers(ILogger<DeleteUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||||
| { | { | ||||
| this.unitOfWork = unitOfWork; | this.unitOfWork = unitOfWork; | ||||
| this.repository = repository; | |||||
| this.mapper = mapper; | this.mapper = mapper; | ||||
| this.logger = logger; | this.logger = logger; | ||||
| } | } | ||||
| public async Task<Result<Guid>> Handle(DeleteUsersCommand command, CancellationToken cancellationToken) | |||||
| public async Task<Result<int>> Handle(DeleteUsersCommand command, CancellationToken cancellationToken) | |||||
| { | { | ||||
| if (command.Id == Guid.Empty) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||||
| if (command.Id <= 0) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||||
| logger.LogInformation("Deleting user ..."); | logger.LogInformation("Deleting user ..."); | ||||
| try | try | ||||
| { | { | ||||
| var user = await repository.GetByIdAsync(command.Id); | |||||
| repository.Remove(user); | |||||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||||
| unitOfWork.UsersRepository.Remove(user); | |||||
| await unitOfWork.SaveChangesAsync(); | await unitOfWork.SaveChangesAsync(); | ||||
| logger.LogInformation($"User with id {user.Id} has been deleted successfully"); | logger.LogInformation($"User with id {user.Id} has been deleted successfully"); | ||||
| return new Result<Guid> { Data = command.Id }; | |||||
| return new Result<int> { Data = command.Id }; | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| return new Result<Guid> { IsSuccess = false, Error = "Faild to delete data from DB." }; | |||||
| return new Result<int> { IsSuccess = false, Error = "Faild to delete data from DB." }; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Controllers.Dto; | |||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| namespace BlackRock.Reporting.API.Mediator | namespace BlackRock.Reporting.API.Mediator | ||||
| { | { | ||||
| public class QueryResults<T> | |||||
| public class GetAllUsersQuery : PaggingAndFiltering, IRequest<Result<PaggingCollection<UserDto>>> | |||||
| { | { | ||||
| public int TotalItems { get; set; } | |||||
| public IEnumerable<T> Items { get; set; } | |||||
| } | |||||
| public class UserQuery | |||||
| { | |||||
| public string SortBy { get; set; } | |||||
| public bool IsSortAscending { get; set; } | |||||
| public int Page { get; set; } | |||||
| public int PageSize { get; set; } | |||||
| } | |||||
| public class GetAllUsersQuery : IRequest<Result<QueryResults<UserDto>>> | |||||
| { | |||||
| public UserQuery Filter { get; } | |||||
| public GetAllUsersQuery(UserQuery filter) | |||||
| { | |||||
| this.Filter = filter; | |||||
| } | |||||
| } | } | ||||
| public class GetAllUsersQueryHandlers : IRequestHandler<GetAllUsersQuery, Result<QueryResults<UserDto>>> | |||||
| public class GetAllUsersQueryHandlers : IRequestHandler<GetAllUsersQuery, Result<PaggingCollection<UserDto>>> | |||||
| { | { | ||||
| private readonly ILogger<GetAllUsersQueryHandlers> logger; | private readonly ILogger<GetAllUsersQueryHandlers> logger; | ||||
| private readonly IMapper mapper; | private readonly IMapper mapper; | ||||
| private readonly IUnitOfWork unitOfWork; | private readonly IUnitOfWork unitOfWork; | ||||
| private readonly IUsersRepository repository; | |||||
| public GetAllUsersQueryHandlers(ILogger<GetAllUsersQueryHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||||
| public GetAllUsersQueryHandlers(ILogger<GetAllUsersQueryHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||||
| { | { | ||||
| this.repository = repository; | |||||
| this.unitOfWork = unitOfWork; | this.unitOfWork = unitOfWork; | ||||
| this.mapper = mapper; | this.mapper = mapper; | ||||
| this.logger = logger; | this.logger = logger; | ||||
| } | } | ||||
| public async Task<Result<QueryResults<UserDto>>> Handle(GetAllUsersQuery command, CancellationToken cancellationToken) | |||||
| public async Task<Result<PaggingCollection<UserDto>>> Handle(GetAllUsersQuery command, CancellationToken cancellationToken) | |||||
| { | { | ||||
| if (command.Filter == null) | |||||
| throw new ArgumentNullException($"Parameter {nameof(command.Filter)} must not be null"); | |||||
| if (command == null) | |||||
| throw new ArgumentNullException($"Parameter {nameof(command)} must not be null"); | |||||
| logger.LogInformation("Getting users ..."); | logger.LogInformation("Getting users ..."); | ||||
| try | try | ||||
| { | { | ||||
| var users = await repository.GetAllAsync(); | |||||
| var usersDto = mapper.Map<IEnumerable<User>, IEnumerable<UserDto>>(users); | |||||
| var data = new QueryResults<UserDto> { Items = usersDto, TotalItems = usersDto.Count() }; | |||||
| var users = await unitOfWork.UsersRepository.GetAllByFilter(command); | |||||
| var usersDto = mapper.Map<PaggingCollection<User>, PaggingCollection<UserDto>>(users); | |||||
| logger.LogInformation($"The Users has been founded successfully"); | logger.LogInformation($"The Users has been founded successfully"); | ||||
| return new Result<QueryResults<UserDto>> { Data = data }; | |||||
| return new Result<PaggingCollection<UserDto>> { Data = usersDto }; | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| return new Result<QueryResults<UserDto>> { IsSuccess = false, Error = "Faild to fetch data from DB." }; | |||||
| return new Result<PaggingCollection<UserDto>> { IsSuccess = false, Error = "Faild to fetch data from DB." }; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Controllers.Dto; | |||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| namespace BlackRock.Reporting.API.Mediator | namespace BlackRock.Reporting.API.Mediator | ||||
| { | { | ||||
| public class GetUsersQuery : IRequest<Result<UserDto>> | |||||
| public class GetUsersQuery : UserQuery, IRequest<Result<UserDto>> | |||||
| { | { | ||||
| public Guid Id { get; } | |||||
| public GetUsersQuery(Guid id) | |||||
| public GetUsersQuery(int id) : base(id) | |||||
| { | { | ||||
| this.Id = id; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| public async Task<Result<UserDto>> Handle(GetUsersQuery command, CancellationToken cancellationToken) | public async Task<Result<UserDto>> Handle(GetUsersQuery command, CancellationToken cancellationToken) | ||||
| { | { | ||||
| if (command.Id == Guid.Empty) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||||
| if (command.Id <= 0) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||||
| logger.LogInformation("Getting user ..."); | logger.LogInformation("Getting user ..."); | ||||
| try | try | ||||
| { | { |
| using Microsoft.AspNetCore.Mvc.ModelBinding; | |||||
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public class ErrorResponse | |||||
| { | |||||
| public IEnumerable<string> Errors { get; set; } | |||||
| public Enum StatusCode { get; set; } | |||||
| public ModelStateDictionary Validations { get; set; } | |||||
| public static ErrorResponse Validation(ModelStateDictionary validations) | |||||
| { | |||||
| return new ErrorResponse | |||||
| { | |||||
| Validations = validations | |||||
| }; | |||||
| } | |||||
| } | |||||
| // I/O | |||||
| // Output: DTO : Entity wraper, Agregations | |||||
| // Input: Query / Form | |||||
| } |
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public interface IPaggingAndFiltering | |||||
| { | |||||
| string EmailDomain {get;set;} | |||||
| string SortBy { get; set; } | |||||
| bool IsSortAscending { get; set; } | |||||
| int Page { get; set; } | |||||
| int PageSize { get; set; } | |||||
| } | |||||
| } |
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public class PaggingAndFiltering : IPaggingAndFiltering | |||||
| { | |||||
| public string EmailDomain { get; set; } | |||||
| public string SortBy {get;set;} | |||||
| public bool IsSortAscending {get;set;} | |||||
| public int Page {get;set;} | |||||
| public int PageSize {get;set;} | |||||
| } | |||||
| } |
| using System.Collections.ObjectModel; | |||||
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public class PaggingCollection<T> : Collection<T>, IPaggingAndFiltering where T : class | |||||
| { | |||||
| public string SortBy {set;get;} | |||||
| public bool IsSortAscending {set;get;} | |||||
| public int Page {set;get;} | |||||
| public int PageSize {set;get;} | |||||
| public string EmailDomain {get;set;} | |||||
| } | |||||
| } |
| using System.ComponentModel.DataAnnotations; | |||||
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public class UserCommand | |||||
| { | |||||
| [Required] | |||||
| public string Name { get; } | |||||
| [Required] | |||||
| public string Email { get; } | |||||
| public UserCommand(string Name,string Email) | |||||
| { | |||||
| this.Name = Name; | |||||
| this.Email = Email; | |||||
| } | |||||
| } | |||||
| } |
| using System.ComponentModel.DataAnnotations; | |||||
| namespace BlackRock.Reporting.API.Mediator.Model | |||||
| { | |||||
| public class UserQuery | |||||
| { | |||||
| [Required] | |||||
| public int Id { get; } | |||||
| public UserQuery(int id) | |||||
| { | |||||
| Id = id; | |||||
| } | |||||
| } | |||||
| } |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Controllers.Dto; | |||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| { | { | ||||
| public class UpdateAllUsersCommand : IRequest<Result<UserDto>> | public class UpdateAllUsersCommand : IRequest<Result<UserDto>> | ||||
| { | { | ||||
| public UserForm User { get; } | |||||
| public Guid Id { get; } | |||||
| public UpdateAllUsersCommand(Guid id, UserForm user) | |||||
| public UserCommand User { get; } | |||||
| public int Id { get; } | |||||
| public UpdateAllUsersCommand(int id, UserCommand user) | |||||
| { | { | ||||
| this.Id = id; | this.Id = id; | ||||
| this.User = user; | this.User = user; | ||||
| { | { | ||||
| private readonly ILogger<UpdateAllUsersCommandHandlers> logger; | private readonly ILogger<UpdateAllUsersCommandHandlers> logger; | ||||
| private readonly IMapper mapper; | private readonly IMapper mapper; | ||||
| private readonly IUsersRepository repository; | |||||
| private readonly IUnitOfWork unitOfWork; | private readonly IUnitOfWork unitOfWork; | ||||
| public UpdateAllUsersCommandHandlers(ILogger<UpdateAllUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||||
| public UpdateAllUsersCommandHandlers(ILogger<UpdateAllUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||||
| { | { | ||||
| this.unitOfWork = unitOfWork; | this.unitOfWork = unitOfWork; | ||||
| this.repository = repository; | |||||
| this.mapper = mapper; | this.mapper = mapper; | ||||
| this.logger = logger; | this.logger = logger; | ||||
| } | } | ||||
| public async Task<Result<UserDto>> Handle(UpdateAllUsersCommand command, CancellationToken cancellationToken) | public async Task<Result<UserDto>> Handle(UpdateAllUsersCommand command, CancellationToken cancellationToken) | ||||
| { | { | ||||
| if (command.Id == Guid.Empty) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||||
| if (command.Id <= 0) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||||
| logger.LogInformation("Updating user ..."); | logger.LogInformation("Updating user ..."); | ||||
| try | try | ||||
| { | { | ||||
| var user = await repository.GetByIdAsync(command.Id); | |||||
| mapper.Map<UserForm, User>(command.User, user); | |||||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||||
| mapper.Map<UserCommand, User>(command.User, user); | |||||
| unitOfWork.UsersRepository.Update(user); | |||||
| await unitOfWork.SaveChangesAsync(); | await unitOfWork.SaveChangesAsync(); | ||||
| var updatedUser = mapper.Map<User, UserDto>(user); | var updatedUser = mapper.Map<User, UserDto>(user); | ||||
| logger.LogInformation($"User with id {user.Id} has been updated successfully"); | logger.LogInformation($"User with id {user.Id} has been updated successfully"); |
| using AutoMapper; | using AutoMapper; | ||||
| using BlackRock.Reporting.API.Controllers.Dto; | |||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using MediatR; | using MediatR; | ||||
| { | { | ||||
| public class UpdateEmailUsersCommand : IRequest<Result<UserDto>> | public class UpdateEmailUsersCommand : IRequest<Result<UserDto>> | ||||
| { | { | ||||
| public UserForm User { get; } | |||||
| public Guid Id { get; } | |||||
| public UpdateEmailUsersCommand(Guid id, UserForm user) | |||||
| public UserCommand User { get; } | |||||
| public int Id { get; } | |||||
| public UpdateEmailUsersCommand(int id, UserCommand user) | |||||
| { | { | ||||
| this.Id = id; | this.Id = id; | ||||
| this.User = user; | this.User = user; | ||||
| { | { | ||||
| private readonly ILogger<UpdateEmailUsersCommandHandlers> logger; | private readonly ILogger<UpdateEmailUsersCommandHandlers> logger; | ||||
| private readonly IMapper mapper; | private readonly IMapper mapper; | ||||
| private readonly IUsersRepository repository; | |||||
| private readonly IUnitOfWork unitOfWork; | private readonly IUnitOfWork unitOfWork; | ||||
| public UpdateEmailUsersCommandHandlers(ILogger<UpdateEmailUsersCommandHandlers> logger, IMapper mapper, IUsersRepository repository, IUnitOfWork unitOfWork) | |||||
| public UpdateEmailUsersCommandHandlers(ILogger<UpdateEmailUsersCommandHandlers> logger, IMapper mapper, IUnitOfWork unitOfWork) | |||||
| { | { | ||||
| this.unitOfWork = unitOfWork; | this.unitOfWork = unitOfWork; | ||||
| this.repository = repository; | |||||
| this.mapper = mapper; | this.mapper = mapper; | ||||
| this.logger = logger; | this.logger = logger; | ||||
| } | } | ||||
| public async Task<Result<UserDto>> Handle(UpdateEmailUsersCommand command, CancellationToken cancellationToken) | public async Task<Result<UserDto>> Handle(UpdateEmailUsersCommand command, CancellationToken cancellationToken) | ||||
| { | { | ||||
| if (command.Id == Guid.Empty) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be null or empty"); | |||||
| if (command.Id <= 0) | |||||
| throw new ArgumentException($"Parameter {nameof(command.Id)} must not be grater than 0"); | |||||
| logger.LogInformation("Updating user email ..."); | logger.LogInformation("Updating user email ..."); | ||||
| try | try | ||||
| { | { | ||||
| var user = await repository.GetByIdAsync(command.Id); | |||||
| user.Email = command.User.Email; | |||||
| var user = await unitOfWork.UsersRepository.GetByIdAsync(command.Id); | |||||
| unitOfWork.UsersRepository.UpdateEmail(user,command.User.Email); | |||||
| await unitOfWork.SaveChangesAsync(); | await unitOfWork.SaveChangesAsync(); | ||||
| var updatedUser = mapper.Map<User, UserDto>(user); | var updatedUser = mapper.Map<User, UserDto>(user); | ||||
| logger.LogInformation($"Email of the user with id {user.Id} has been updated successfully"); | logger.LogInformation($"Email of the user with id {user.Id} has been updated successfully"); |
| // <auto-generated /> | |||||
| using BlackRock.Reporting.API.Persistence; | |||||
| using Microsoft.EntityFrameworkCore; | |||||
| using Microsoft.EntityFrameworkCore.Infrastructure; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | |||||
| #nullable disable | |||||
| namespace BlackRock.Reporting.API.Migrations | |||||
| { | |||||
| [DbContext(typeof(BRDbContext))] | |||||
| [Migration("20211123150542_ChangedIdFromGuidToInt")] | |||||
| partial class ChangedIdFromGuidToInt | |||||
| { | |||||
| protected override void BuildTargetModel(ModelBuilder modelBuilder) | |||||
| { | |||||
| #pragma warning disable 612, 618 | |||||
| modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); | |||||
| modelBuilder.Entity("BlackRock.Reporting.API.Models.User", b => | |||||
| { | |||||
| b.Property<int>("Id") | |||||
| .ValueGeneratedOnAdd() | |||||
| .HasColumnType("INTEGER"); | |||||
| b.Property<string>("Email") | |||||
| .HasColumnType("TEXT"); | |||||
| b.Property<string>("Name") | |||||
| .HasColumnType("TEXT"); | |||||
| b.HasKey("Id"); | |||||
| b.ToTable("Users"); | |||||
| }); | |||||
| #pragma warning restore 612, 618 | |||||
| } | |||||
| } | |||||
| } |
| using System; | |||||
| using Microsoft.EntityFrameworkCore.Migrations; | |||||
| #nullable disable | |||||
| namespace BlackRock.Reporting.API.Migrations | |||||
| { | |||||
| public partial class ChangedIdFromGuidToInt : Migration | |||||
| { | |||||
| protected override void Up(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.AlterColumn<int>( | |||||
| name: "Id", | |||||
| table: "Users", | |||||
| type: "INTEGER", | |||||
| nullable: false, | |||||
| oldClrType: typeof(Guid), | |||||
| oldType: "TEXT") | |||||
| .Annotation("Sqlite:Autoincrement", true); | |||||
| } | |||||
| protected override void Down(MigrationBuilder migrationBuilder) | |||||
| { | |||||
| migrationBuilder.AlterColumn<Guid>( | |||||
| name: "Id", | |||||
| table: "Users", | |||||
| type: "TEXT", | |||||
| nullable: false, | |||||
| oldClrType: typeof(int), | |||||
| oldType: "INTEGER") | |||||
| .OldAnnotation("Sqlite:Autoincrement", true); | |||||
| } | |||||
| } | |||||
| } |
| // <auto-generated /> | // <auto-generated /> | ||||
| using System; | |||||
| using BlackRock.Reporting.API.Persistence; | using BlackRock.Reporting.API.Persistence; | ||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||
| using Microsoft.EntityFrameworkCore.Infrastructure; | using Microsoft.EntityFrameworkCore.Infrastructure; | ||||
| modelBuilder.Entity("BlackRock.Reporting.API.Models.User", b => | modelBuilder.Entity("BlackRock.Reporting.API.Models.User", b => | ||||
| { | { | ||||
| b.Property<Guid>("Id") | |||||
| b.Property<int>("Id") | |||||
| .ValueGeneratedOnAdd() | .ValueGeneratedOnAdd() | ||||
| .HasColumnType("TEXT"); | |||||
| .HasColumnType("INTEGER"); | |||||
| b.Property<string>("Email") | b.Property<string>("Email") | ||||
| .HasColumnType("TEXT"); | .HasColumnType("TEXT"); |
| namespace BlackRock.Reporting.API.Models | |||||
| { | |||||
| public interface IBaseEntity | |||||
| { | |||||
| public int Id { get; set; } | |||||
| } | |||||
| } |
| namespace BlackRock.Reporting.API.Models | namespace BlackRock.Reporting.API.Models | ||||
| { | { | ||||
| public class User | |||||
| { | |||||
| public Guid Id { get; set; } | |||||
| public string? Name { get; set; } | |||||
| public string? Email { get; set; } | |||||
| } | |||||
| public class UserDto | |||||
| public class User : IBaseEntity | |||||
| { | { | ||||
| public int Id { get; set; } | |||||
| public string? Name { get; set; } | public string? Name { get; set; } | ||||
| public string? Email { get; set; } | public string? Email { get; set; } | ||||
| } | } |
| using System.ComponentModel.DataAnnotations; | |||||
| namespace BlackRock.Reporting.API.Models | |||||
| { | |||||
| public class UserForm | |||||
| { | |||||
| [Required] | |||||
| public string? Name { get; set; } | |||||
| [Required] | |||||
| public string? Email { get; set; } | |||||
| } | |||||
| } |
| { | { | ||||
| } | } | ||||
| public DbSet<User> Users { get; set; } | public DbSet<User> Users { get; set; } | ||||
| } | } | ||||
| } | } |
| using System.Linq.Expressions; | using System.Linq.Expressions; | ||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Core.Models; | using BlackRock.Reporting.API.Core.Models; | ||||
| using BlackRock.Reporting.API.Models; | |||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||
| namespace BlackRock.Reporting.API.Persistence | namespace BlackRock.Reporting.API.Persistence | ||||
| { | { | ||||
| // Q: Da li da dozvolimo promene van klase ili da zabranimo pomocu AsNoTracking(); | |||||
| public class Repository<TEntity> : IRepository<TEntity> where TEntity : class | |||||
| public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IBaseEntity | |||||
| { | { | ||||
| private readonly BRDbContext context; | private readonly BRDbContext context; | ||||
| public Repository(BRDbContext context) | public Repository(BRDbContext context) | ||||
| { | { | ||||
| this.context = context; | this.context = context; | ||||
| } | } | ||||
| public async Task<IQueryable<TEntity>> GetAllAsync() | |||||
| public async Task<IEnumerable<TEntity>> GetAllAsync() | |||||
| { | { | ||||
| var result = await context.Set<TEntity>().ToListAsync(); | |||||
| return result.AsQueryable(); | |||||
| return await context.Set<TEntity>().ToListAsync(); | |||||
| } | } | ||||
| public async Task<TEntity> GetByIdAsync(Guid id) | |||||
| public async Task<TEntity> GetByIdAsync(int id) | |||||
| { | { | ||||
| return await context.Set<TEntity>() | return await context.Set<TEntity>() | ||||
| .FindAsync(id); | .FindAsync(id); | ||||
| { | { | ||||
| await context.Set<TEntity>().AddAsync(entity); | await context.Set<TEntity>().AddAsync(entity); | ||||
| } | } | ||||
| public void Update(TEntity entity) | |||||
| { | |||||
| context.Set<TEntity>().Update(entity); | |||||
| } | |||||
| public void UpdateRange(IEnumerable<TEntity> entities) | |||||
| { | |||||
| context.Set<TEntity>().UpdateRange(entities); | |||||
| } | |||||
| public async Task AddRangeAsync(IEnumerable<TEntity> entities) | public async Task AddRangeAsync(IEnumerable<TEntity> entities) | ||||
| { | { | ||||
| await context.Set<TEntity>().AddRangeAsync(entities); | await context.Set<TEntity>().AddRangeAsync(entities); |
| public class UnitOfWork : IUnitOfWork | public class UnitOfWork : IUnitOfWork | ||||
| { | { | ||||
| private readonly BRDbContext context; | private readonly BRDbContext context; | ||||
| public UnitOfWork(BRDbContext context) | |||||
| public IUsersRepository UsersRepository { get; set; } | |||||
| public UnitOfWork(BRDbContext context, IUsersRepository usersRepository) | |||||
| { | { | ||||
| this.UsersRepository = usersRepository; | |||||
| this.context = context; | this.context = context; | ||||
| } | } | ||||
| using System.Linq.Expressions; | |||||
| using BlackRock.Reporting.API.Core; | using BlackRock.Reporting.API.Core; | ||||
| using BlackRock.Reporting.API.Extensions; | |||||
| using BlackRock.Reporting.API.Mediator; | |||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using Microsoft.EntityFrameworkCore; | |||||
| namespace BlackRock.Reporting.API.Persistence | namespace BlackRock.Reporting.API.Persistence | ||||
| { | { | ||||
| { | { | ||||
| this.context = context; | this.context = context; | ||||
| } | } | ||||
| public async Task<PaggingCollection<User>> GetAllByFilter(PaggingAndFiltering queryObj) | |||||
| { | |||||
| var result = new PaggingCollection<User>(); | |||||
| var queryResult = await context.Users.ToListAsync(); | |||||
| var query = queryResult.AsQueryable(); | |||||
| // filtering | |||||
| if (!string.IsNullOrWhiteSpace(queryObj.EmailDomain)) | |||||
| query = query.Where(q => q.Email.EndsWith(queryObj.EmailDomain.ToLower())); | |||||
| // sorting | |||||
| var columnsMap = new Dictionary<string, Expression<Func<User, object>>>() | |||||
| { | |||||
| ["name"] = u => u.Name, | |||||
| ["email"] = u => u.Email | |||||
| }; | |||||
| query = query.ApplyOrdering(queryObj, columnsMap); | |||||
| query = query.ApplyPagging(queryObj); | |||||
| foreach (var item in query) | |||||
| { | |||||
| result.Add(item); | |||||
| } | |||||
| return result; | |||||
| // pagging | |||||
| } | |||||
| public void UpdateEmail(User user, string email) | |||||
| { | |||||
| user.Email = email; | |||||
| this.Update(user); | |||||
| } | |||||
| } | } | ||||
| } | } |
| using PuppeteerSharp; | using PuppeteerSharp; | ||||
| using BlackRock.Reporting.API.Core.Models; | using BlackRock.Reporting.API.Core.Models; | ||||
| using BlackRock.Reporting.API.Models; | using BlackRock.Reporting.API.Models; | ||||
| using BlackRock.Reporting.API.Mediator.Model; | |||||
| using BlackRock.Reporting.API.Controllers.Dto; | |||||
| namespace BlackRock.Reporting.API.Profiles | namespace BlackRock.Reporting.API.Profiles | ||||
| { | { | ||||
| { | { | ||||
| CreateMap<OptionsForPdf, PdfOptions>().ConvertUsing<OptionsForPdfConverter>(); | CreateMap<OptionsForPdf, PdfOptions>().ConvertUsing<OptionsForPdfConverter>(); | ||||
| CreateMap<User, UserDto>().ReverseMap(); | CreateMap<User, UserDto>().ReverseMap(); | ||||
| CreateMap<User, UserForm>().ReverseMap(); | |||||
| CreateMap<User, UserCommand>().ReverseMap(); | |||||
| } | } | ||||
| } | } | ||||
| 2.0 | 2.0 | ||||
| 2.0 | 2.0 | ||||
| 2.0 | 2.0 | ||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 | |||||
| 2.0 |