From c312a24ab5c9dd41f945fbb27c7c011735668feb Mon Sep 17 00:00:00 2001 From: Phong Nguyen Date: Thu, 25 May 2023 08:54:54 +0700 Subject: [PATCH] Product Service: switching to MediatR is super straightforward --- .../ClassifiedAds.Services.Product.Api.csproj | 1 + .../Commands/AddAuditLogEntryCommand.cs | 11 ++++---- .../Commands/AddUpdateProductCommand.cs | 7 +++-- .../Commands/DeleteProductCommand.cs | 7 +++-- .../Controllers/ProductsController.cs | 28 +++++++++---------- .../ProductCreatedEventHandler.cs | 10 +++---- .../ProductDeletedEventHandler.cs | 10 +++---- .../ProductUpdatedEventHandler.cs | 10 +++---- ...roductModuleServiceCollectionExtensions.cs | 2 +- .../Queries/GetAuditEntriesQuery.cs | 16 +++++------ .../Queries/GetProductQuery.cs | 10 +++---- .../Queries/GetProductsQuery.cs | 10 +++---- .../Queries/GetUsersQuery.cs | 10 +++---- 13 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ClassifiedAds.Services.Product.Api.csproj b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ClassifiedAds.Services.Product.Api.csproj index aabdb92c4..c4db4a18b 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ClassifiedAds.Services.Product.Api.csproj +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ClassifiedAds.Services.Product.Api.csproj @@ -13,6 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/AddAuditLogEntryCommand.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/AddAuditLogEntryCommand.cs index 6f00ad516..08bd1918a 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/AddAuditLogEntryCommand.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/AddAuditLogEntryCommand.cs @@ -1,20 +1,19 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; +using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; using ClassifiedAds.Domain.Repositories; using ClassifiedAds.Infrastructure.Identity; using ClassifiedAds.Services.Product.Entities; +using MediatR; using System; using System.Threading; using System.Threading.Tasks; - namespace ClassifiedAds.Services.Product.Commands; -public class AddAuditLogEntryCommand : ICommand +public class AddAuditLogEntryCommand : IRequest { public AuditLogEntry AuditLogEntry { get; set; } } -public class AddAuditLogEntryCommandHandler : ICommandHandler +public class AddAuditLogEntryCommandHandler : IRequestHandler { private readonly ICurrentUser _currentUser; private readonly IRepository _auditLogRepository; @@ -30,7 +29,7 @@ public class AddAuditLogEntryCommandHandler : ICommandHandler +public class AddUpdateProductCommandHandler : IRequestHandler { private readonly ICrudService _productService; @@ -18,7 +19,7 @@ public AddUpdateProductCommandHandler(ICrudService productServ _productService = productService; } - public async Task HandleAsync(AddUpdateProductCommand command, CancellationToken cancellationToken = default) + public async Task Handle(AddUpdateProductCommand command, CancellationToken cancellationToken = default) { await _productService.AddOrUpdateAsync(command.Product); } diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/DeleteProductCommand.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/DeleteProductCommand.cs index 48ef86a7e..e8cc00eaa 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/DeleteProductCommand.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Commands/DeleteProductCommand.cs @@ -1,15 +1,16 @@ using ClassifiedAds.Application; +using MediatR; using System.Threading; using System.Threading.Tasks; namespace ClassifiedAds.Services.Product.Commands; -public class DeleteProductCommand : ICommand +public class DeleteProductCommand : IRequest { public Entities.Product Product { get; set; } } -public class DeleteProductCommandHandler : ICommandHandler +public class DeleteProductCommandHandler : IRequestHandler { private readonly ICrudService _productService; @@ -18,7 +19,7 @@ public DeleteProductCommandHandler(ICrudService productService _productService = productService; } - public async Task HandleAsync(DeleteProductCommand command, CancellationToken cancellationToken = default) + public async Task Handle(DeleteProductCommand command, CancellationToken cancellationToken = default) { await _productService.DeleteAsync(command.Product); } diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Controllers/ProductsController.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Controllers/ProductsController.cs index 7c18d7190..1fb7a0f8c 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Controllers/ProductsController.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Controllers/ProductsController.cs @@ -1,5 +1,4 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.Csv; +using ClassifiedAds.CrossCuttingConcerns.Csv; using ClassifiedAds.CrossCuttingConcerns.HtmlGenerator; using ClassifiedAds.CrossCuttingConcerns.PdfConverter; using ClassifiedAds.Services.Product.Authorization; @@ -8,6 +7,7 @@ using ClassifiedAds.Services.Product.Models; using ClassifiedAds.Services.Product.Queries; using ClassifiedAds.Services.Product.RateLimiterPolicies; +using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -30,14 +30,14 @@ namespace ClassifiedAds.Services.Product.Controllers; [ApiController] public class ProductsController : ControllerBase { - private readonly Dispatcher _dispatcher; + private readonly IMediator _dispatcher; private readonly ILogger _logger; private readonly IHtmlGenerator _htmlGenerator; private readonly IPdfConverter _pdfConverter; private readonly ICsvWriter _productCsvWriter; private readonly ICsvReader _productCsvReader; - public ProductsController(Dispatcher dispatcher, + public ProductsController(IMediator dispatcher, ILogger logger, IHtmlGenerator htmlGenerator, IPdfConverter pdfConverter, @@ -57,7 +57,7 @@ public class ProductsController : ControllerBase public async Task>> Get() { _logger.LogInformation("Getting all products"); - var products = await _dispatcher.DispatchAsync(new GetProductsQuery()); + var products = await _dispatcher.Send(new GetProductsQuery()); var model = products.ToModels(); return Ok(model); } @@ -68,7 +68,7 @@ public async Task>> Get() [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Get(Guid id) { - var product = await _dispatcher.DispatchAsync(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); + var product = await _dispatcher.Send(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); var model = product.ToModel(); return Ok(model); } @@ -80,7 +80,7 @@ public async Task> Get(Guid id) public async Task> Post([FromBody] ProductModel model) { var product = model.ToEntity(); - await _dispatcher.DispatchAsync(new AddUpdateProductCommand { Product = product }); + await _dispatcher.Send(new AddUpdateProductCommand { Product = product }); model = product.ToModel(); return Created($"/api/products/{model.Id}", model); } @@ -92,13 +92,13 @@ public async Task> Post([FromBody] ProductModel m [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Put(Guid id, [FromBody] ProductModel model) { - var product = await _dispatcher.DispatchAsync(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); + var product = await _dispatcher.Send(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); product.Code = model.Code; product.Name = model.Name; product.Description = model.Description; - await _dispatcher.DispatchAsync(new AddUpdateProductCommand { Product = product }); + await _dispatcher.Send(new AddUpdateProductCommand { Product = product }); model = product.ToModel(); @@ -111,9 +111,9 @@ public async Task Put(Guid id, [FromBody] ProductModel model) [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Delete(Guid id) { - var product = await _dispatcher.DispatchAsync(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); + var product = await _dispatcher.Send(new GetProductQuery { Id = id, ThrowNotFoundIfNull = true }); - await _dispatcher.DispatchAsync(new DeleteProductCommand { Product = product }); + await _dispatcher.Send(new DeleteProductCommand { Product = product }); return Ok(); } @@ -122,7 +122,7 @@ public async Task Delete(Guid id) [HttpGet("{id}/auditlogs")] public async Task>> GetAuditLogs(Guid id) { - var logs = await _dispatcher.DispatchAsync(new GetAuditEntriesQuery { ObjectId = id.ToString() }); + var logs = await _dispatcher.Send(new GetAuditEntriesQuery { ObjectId = id.ToString() }); List entries = new List(); ProductModel previous = null; @@ -156,7 +156,7 @@ public async Task>> GetAuditLogs(Guid [HttpGet("exportaspdf")] public async Task ExportAsPdf() { - var products = await _dispatcher.DispatchAsync(new GetProductsQuery()); + var products = await _dispatcher.Send(new GetProductsQuery()); var model = products.ToModels(); var template = Path.Combine(Environment.CurrentDirectory, $"Templates/ProductList.cshtml"); @@ -169,7 +169,7 @@ public async Task ExportAsPdf() [HttpGet("exportascsv")] public async Task ExportAsCsv() { - var products = await _dispatcher.DispatchAsync(new GetProductsQuery()); + var products = await _dispatcher.Send(new GetProductsQuery()); var model = products.ToModels(); using var stream = new MemoryStream(); _productCsvWriter.Write(model, stream); diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductCreatedEventHandler.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductCreatedEventHandler.cs index 69557f5a1..52913e7dc 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductCreatedEventHandler.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductCreatedEventHandler.cs @@ -1,10 +1,10 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; +using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; using ClassifiedAds.Domain.Events; using ClassifiedAds.Domain.Repositories; using ClassifiedAds.Infrastructure.Identity; using ClassifiedAds.Services.Product.Commands; using ClassifiedAds.Services.Product.Entities; +using MediatR; using System; using System.Threading; using System.Threading.Tasks; @@ -13,11 +13,11 @@ namespace ClassifiedAds.Services.Product.EventHandlers; public class ProductCreatedEventHandler : IDomainEventHandler> { - private readonly Dispatcher _dispatcher; + private readonly IMediator _dispatcher; private readonly ICurrentUser _currentUser; private readonly IRepository _outboxEventRepository; - public ProductCreatedEventHandler(Dispatcher dispatcher, + public ProductCreatedEventHandler(IMediator dispatcher, ICurrentUser currentUser, IRepository outboxEventRepository) { @@ -28,7 +28,7 @@ public class ProductCreatedEventHandler : IDomainEventHandler domainEvent, CancellationToken cancellationToken = default) { - await _dispatcher.DispatchAsync(new AddAuditLogEntryCommand + await _dispatcher.Send(new AddAuditLogEntryCommand { AuditLogEntry = new AuditLogEntry { diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductDeletedEventHandler.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductDeletedEventHandler.cs index 0ee8d4e51..76446b6db 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductDeletedEventHandler.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductDeletedEventHandler.cs @@ -1,10 +1,10 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; +using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; using ClassifiedAds.Domain.Events; using ClassifiedAds.Domain.Repositories; using ClassifiedAds.Infrastructure.Identity; using ClassifiedAds.Services.Product.Commands; using ClassifiedAds.Services.Product.Entities; +using MediatR; using System.Threading; using System.Threading.Tasks; @@ -12,11 +12,11 @@ namespace ClassifiedAds.Services.Product.EventHandlers; public class ProductDeletedEventHandler : IDomainEventHandler> { - private readonly Dispatcher _dispatcher; + private readonly IMediator _dispatcher; private readonly ICurrentUser _currentUser; private readonly IRepository _outboxEventRepository; - public ProductDeletedEventHandler(Dispatcher dispatcher, + public ProductDeletedEventHandler(IMediator dispatcher, ICurrentUser currentUser, IRepository outboxEventRepository) { @@ -27,7 +27,7 @@ public class ProductDeletedEventHandler : IDomainEventHandler domainEvent, CancellationToken cancellationToken = default) { - await _dispatcher.DispatchAsync(new AddAuditLogEntryCommand + await _dispatcher.Send(new AddAuditLogEntryCommand { AuditLogEntry = new AuditLogEntry { diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductUpdatedEventHandler.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductUpdatedEventHandler.cs index 50411de46..65bb04df6 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductUpdatedEventHandler.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/EventHandlers/ProductUpdatedEventHandler.cs @@ -1,10 +1,10 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; +using ClassifiedAds.CrossCuttingConcerns.ExtensionMethods; using ClassifiedAds.Domain.Events; using ClassifiedAds.Domain.Repositories; using ClassifiedAds.Infrastructure.Identity; using ClassifiedAds.Services.Product.Commands; using ClassifiedAds.Services.Product.Entities; +using MediatR; using System.Threading; using System.Threading.Tasks; @@ -12,11 +12,11 @@ namespace ClassifiedAds.Services.Product.EventHandlers; public class ProductUpdatedEventHandler : IDomainEventHandler> { - private readonly Dispatcher _dispatcher; + private readonly IMediator _dispatcher; private readonly ICurrentUser _currentUser; private readonly IRepository _outboxEventRepository; - public ProductUpdatedEventHandler(Dispatcher dispatcher, + public ProductUpdatedEventHandler(IMediator dispatcher, ICurrentUser currentUser, IRepository outboxEventRepository) { @@ -27,7 +27,7 @@ public class ProductUpdatedEventHandler : IDomainEventHandler domainEvent, CancellationToken cancellationToken = default) { - await _dispatcher.DispatchAsync(new AddAuditLogEntryCommand + await _dispatcher.Send(new AddAuditLogEntryCommand { AuditLogEntry = new AuditLogEntry { diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ProductModuleServiceCollectionExtensions.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ProductModuleServiceCollectionExtensions.cs index 335055ae7..3d34e2948 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ProductModuleServiceCollectionExtensions.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/ProductModuleServiceCollectionExtensions.cs @@ -37,7 +37,7 @@ public static IServiceCollection AddProductModule(this IServiceCollection servic DomainEvents.RegisterHandlers(Assembly.GetExecutingAssembly(), services); - services.AddMessageHandlers(Assembly.GetExecutingAssembly()); + services.AddMediatR(config => config.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly())); services.AddAuthorizationPolicies(Assembly.GetExecutingAssembly(), AuthorizationPolicyNames.GetPolicyNames()); diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetAuditEntriesQuery.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetAuditEntriesQuery.cs index 256db0351..7a4cc3b39 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetAuditEntriesQuery.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetAuditEntriesQuery.cs @@ -1,7 +1,7 @@ -using ClassifiedAds.Application; -using ClassifiedAds.Services.Product.DTOs; +using ClassifiedAds.Services.Product.DTOs; using ClassifiedAds.Services.Product.Entities; using ClassifiedAds.Services.Product.Repositories; +using MediatR; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; @@ -11,22 +11,22 @@ namespace ClassifiedAds.Services.Product.Queries; -public class GetAuditEntriesQuery : AuditLogEntryQueryOptions, IQuery> +public class GetAuditEntriesQuery : AuditLogEntryQueryOptions, IRequest> { } -public class GetAuditEntriesQueryHandler : IQueryHandler> +public class GetAuditEntriesQueryHandler : IRequestHandler> { private readonly ProductDbContext _dbContext; - private readonly Dispatcher _dispatcher; + private readonly IMediator _dispatcher; - public GetAuditEntriesQueryHandler(ProductDbContext dbContext, Dispatcher dispatcher) + public GetAuditEntriesQueryHandler(ProductDbContext dbContext, IMediator dispatcher) { _dbContext = dbContext; _dispatcher = dispatcher; } - public async Task> HandleAsync(GetAuditEntriesQuery queryOptions, CancellationToken cancellationToken = default) + public async Task> Handle(GetAuditEntriesQuery queryOptions, CancellationToken cancellationToken = default) { var query = _dbContext.Set() as IQueryable; @@ -46,7 +46,7 @@ public async Task> HandleAsync(GetAuditEntriesQuery query } var auditLogs = await query.ToListAsync(); - var users = await _dispatcher.DispatchAsync(new GetUsersQuery(), cancellationToken); + var users = await _dispatcher.Send(new GetUsersQuery(), cancellationToken); var rs = auditLogs.Join(users, x => x.UserId, y => y.Id, (x, y) => new AuditLogEntryDTO diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductQuery.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductQuery.cs index 77a9172d2..59ecb9078 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductQuery.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductQuery.cs @@ -1,6 +1,6 @@ -using ClassifiedAds.Application; -using ClassifiedAds.CrossCuttingConcerns.Exceptions; +using ClassifiedAds.CrossCuttingConcerns.Exceptions; using ClassifiedAds.Services.Product.Repositories; +using MediatR; using System; using System.Linq; using System.Threading; @@ -8,13 +8,13 @@ namespace ClassifiedAds.Services.Product.Queries; -public class GetProductQuery : IQuery +public class GetProductQuery : IRequest { public Guid Id { get; set; } public bool ThrowNotFoundIfNull { get; set; } } -public class GetProductQueryHandler : IQueryHandler +public class GetProductQueryHandler : IRequestHandler { private readonly IProductRepository _productRepository; @@ -23,7 +23,7 @@ public GetProductQueryHandler(IProductRepository productRepository) _productRepository = productRepository; } - public async Task HandleAsync(GetProductQuery query, CancellationToken cancellationToken = default) + public async Task Handle(GetProductQuery query, CancellationToken cancellationToken = default) { var product = await _productRepository.FirstOrDefaultAsync(_productRepository.GetAll().Where(x => x.Id == query.Id)); diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductsQuery.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductsQuery.cs index 00b2ec251..7d1d0b9cf 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductsQuery.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetProductsQuery.cs @@ -1,16 +1,16 @@ -using ClassifiedAds.Application; -using ClassifiedAds.Services.Product.Repositories; +using ClassifiedAds.Services.Product.Repositories; +using MediatR; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace ClassifiedAds.Services.Product.Queries; -public class GetProductsQuery : IQuery> +public class GetProductsQuery : IRequest> { } -public class GetProductsQueryHandler : IQueryHandler> +public class GetProductsQueryHandler : IRequestHandler> { private readonly IProductRepository _productRepository; @@ -19,7 +19,7 @@ public GetProductsQueryHandler(IProductRepository productRepository) _productRepository = productRepository; } - public Task> HandleAsync(GetProductsQuery query, CancellationToken cancellationToken = default) + public Task> Handle(GetProductsQuery query, CancellationToken cancellationToken = default) { return _productRepository.ToListAsync(_productRepository.GetAll()); } diff --git a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetUsersQuery.cs b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetUsersQuery.cs index f5aa2dc79..85865bcd6 100644 --- a/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetUsersQuery.cs +++ b/src/Microservices/Services.Product/ClassifiedAds.Services.Product.Api/Queries/GetUsersQuery.cs @@ -1,8 +1,8 @@ -using ClassifiedAds.Application; -using ClassifiedAds.Infrastructure.Grpc; +using ClassifiedAds.Infrastructure.Grpc; using ClassifiedAds.Services.Identity.Grpc; using ClassifiedAds.Services.Product.DTOs; using Grpc.Core; +using MediatR; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; @@ -15,7 +15,7 @@ namespace ClassifiedAds.Services.Product.Queries; -public class GetUsersQuery : IQuery> +public class GetUsersQuery : IRequest> { public bool IncludeClaims { get; set; } public bool IncludeUserRoles { get; set; } @@ -23,7 +23,7 @@ public class GetUsersQuery : IQuery> public bool AsNoTracking { get; set; } } -public class GetUsersQueryHandler : IQueryHandler> +public class GetUsersQueryHandler : IRequestHandler> { private readonly IConfiguration _configuration; private readonly IHttpContextAccessor _httpContextAccessor; @@ -34,7 +34,7 @@ public GetUsersQueryHandler(IConfiguration configuration, IHttpContextAccessor h _httpContextAccessor = httpContextAccessor; } - public async Task> HandleAsync(GetUsersQuery query, CancellationToken cancellationToken = default) + public async Task> Handle(GetUsersQuery query, CancellationToken cancellationToken = default) { var token = await _httpContextAccessor.HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken); var headers = new Metadata