Используйте интерфейс для разрешения MediatR IRequestHandler вместо класса

#c# #cqrs #.net-5 #mediatr

Вопрос:

Я реализовал MediatR в приложении .net 5 и хочу разрешить требуемые зависимости с помощью интерфейсов обработчиков. В настоящее время я использую имя класса для решения следующих задач

 _mediator.Send(new GetDeviceByIMEI(imei)); // want to use interface ??

 //var result = await _mediator.Send(IGetHandHeldByIMEI????);
 

полная ссылка на код выглядит следующим образом;

Интерфейс обработчика

  public interface IGetDeviceByIMEIEventHandler
{
    Task<DeviceWrapperDataView> Handle(GetDeviceByIMEI request, CancellationToken cancellationToken);
}
 

Интерфейс запросов

 public interface IGetDeviceByIMEI
{
    string IMEI { get; set; }
}
 

Запрос

  public class GetDeviceByIMEI: IRequest<DeviceWrapperDataView>
{

    public string IMEI { get; set; }

    public GetDeviceByIMEI(string imei)
    {
        this.IMEI = imei;
    }
}
 

Обработчик

 public class GetDeviceByIMEIEventHandler : IRequestHandler<GetDeviceByIMEI, DeviceWrapperDataView>, IGetDeviceByIMEIEventHandler
{      
    private readonly IDeviceEntity _DeviceEntity;
  
    public GetDeviceByIMEIEventHandler(IDeviceEntity DeviceEntity)
    {
        _DeviceEntity = DeviceEntity;
    }


    public async Task<DeviceWrapperDataView> Handle(GetDeviceByIMEI request, CancellationToken cancellationToken)
    {
        // code to get data 
        return DeviceOutput;
    }
}
 

Контроллер API

 private readonly IMediator _mediator;

  public DeviceController(
        IMediator mediator)
    {
        _mediator = mediator;
    }

 [HttpGet()]
 public async Task<IActionResult> GetDeviceByIMEI(string imei)
 {
   Var result = await _mediator.Send(new GetDeviceByIMEI(imei));
   // want to use 
  }
 

Ответ №1:

Для этого вам необходимо зарегистрировать свой обработчик в контейнере для каждого класса, который наследует ваш интерфейс запроса.

Например, с помощью предоставленного вами кода.

 public interface IGetDeviceByIMEI : IRequest<DeviceWrapperDataView>
{
    string IMEI { get; set; }
}


public class GetDeviceByIMEI: IGetDeviceByIMEI 
{

    public string IMEI { get; set; }

    public GetDeviceByIMEI(string imei)
    {
        this.IMEI = imei;
    }
}

public class AnotherGetDeviceByIMEI: IGetDeviceByIMEI 
{
    
    public string IMEI { get; set; }
    
    public GetDeviceByIMEI(string imei)
    {
        this.IMEI = imei;
    }
}

public class GetDeviceByIMEIEventHandler : IRequestHandler<IGetDeviceByIMEI, DeviceWrapperDataView>, IGetDeviceByIMEIEventHandler
{      
    private readonly IDeviceEntity _DeviceEntity;
  
    public GetDeviceByIMEIEventHandler(IDeviceEntity DeviceEntity)
    {
        _DeviceEntity = DeviceEntity;
    }


    public async Task<DeviceWrapperDataView> Handle(IGetDeviceByIMEI request, CancellationToken cancellationToken)
    {
        // code to get data 
        return DeviceOutput;
    }
}
 

Как только вы это сделаете, вы должны зарегистрировать обработчик в своем контейнере для каждого варианта использования.

Например, в .Net Core вы можете сделать это с помощью коллекции служб в классе запуска.

 serviceCollection.AddTransient<IRequestHandler<GetDeviceByIMEI, DeviceWrapperDataView>, GetDeviceByIMEIEventHandler >();
serviceCollection.AddTransient<IRequestHandler<AnotherGetDeviceByIMEI, DeviceWrapperDataView>, GetDeviceByIMEIEventHandler >();
 

С уважением.