I implemented event listener for incoming messages to my RabbitMQ queue:
//Presentation layer in CQRS
public async Task ReceiveAsync<T>(string queue, Action<T> onMessage)
{
_channel.QueueDeclare(queue, true, false, false);
var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.Received += async (s, e) =>
{
var jsonSpecified = Encoding.UTF8.GetString(e.Body.Span);
var item = JsonSerializer.Deserialize<RabbitRecieverWrapperModel>(jsonSpecified);
string methodName = "GetTypes";
//Get the method information using the method info class
MethodInfo mi = this.GetType().GetMethod(methodName);
//Invoke the method
// (null- no parameter for the method call
// or you can pass the array of parameters...)
mi.Invoke(this, null);
//onMessage(item);
await Task.Yield();
};
_channel.BasicConsume(queue, true, consumer);
await Task.Yield();
}
Methods that I want to call based on message that I recevie from RabbitMQ resides in the Core Project: For example this is one method that I should call from my event listener
namespace SefService.Application.Invoices.Queries
{
public class GetUnitOfMeasuresQuery : IRequest<Result<IList<UnitOfMeasureResponseDto>>>
{
}
public class GetUnitOfMeasuresQueryHandler : IRequestHandler<GetUnitOfMeasuresQuery, Result<IList<UnitOfMeasureResponseDto>>>
{
public ILogger<UnitOfMeasureResponseDto> _logger { get; }
private readonly ISefProxy _sefProxy;
public GetUnitOfMeasuresQueryHandler(ISefProxy sefProxy, ILogger<UnitOfMeasureResponseDto> logger)
{
_logger = logger;
_sefProxy = sefProxy;
}
public async Task<Result<IList<UnitOfMeasureResponseDto>>> Handle(GetUnitOfMeasuresQuery request, CancellationToken cancellationToken)
{
try
{
if (request is null)
{
throw new ArgumentNullException(nameof(request));
}
var response = await _sefProxy.GetUnitOfMeasures();
return new Result<IList<UnitOfMeasureResponseDto>> { Data = response.Data };
}
catch (System.Exception ex)
{
_logger.LogError(ex.Message, ex);
throw new ApiException(ex.Message);
}
}
}
}
Also standard call for this method, from standard WebApi (Swagger) would be like this:
/// <summary>
/// GetUnitOfMeasures
/// </summary>
/// <returns></returns>
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesDefaultResponseType]
[Route(nameof(GetUnitOfMeasures))]
[HttpGet]
public async Task<IActionResult> GetUnitOfMeasures()
{
return Ok(await Mediator.Send(new GetUnitOfMeasuresQuery()));
}
Here is the screenshot of my project and classes: https://i.imgur.com/WWkQzMl.png
I started with using reflection, but I really need to use reflection on another class (Command in CQRS pattern, which resides in separate project).
Should I continue to use reflation in order to distinguish which Command (method) should I call based on message (in message I will have string method name) or do I maybe need to use Chain Of Responsibility pattern? What is the best practice here?
Aucun commentaire:
Enregistrer un commentaire