Please see the synchronous code below:
public class PersonHandler : IRequestHandler<Person, Person>
{
public Task<Person> Handle(Person request, CancellationToken cancellationToken)
{
request.ID = 1;
request.Name = "Brian";
request.Age = 53;
return Task.FromResult(request);
}
}
and the calling code below:
var response2 = mediator.Send(new Person());
This works as expected. Please see the asynchronous code below:
public class PersonHandlerAsync : IRequestHandler<Person, Person>
{
public async Task<Person> Handle(Person request, CancellationToken cancellationToken)
{
request.ID = 1;
request.Name = "Brian";
request.Age = 53;
var result = await Task.FromResult(request);
await Task.Delay(30000);
return result;
}
}
and the calling code below:
var response = Task.Run(() => mediator.Send(new Person()));
This code works as expected.
Is it possible to have two handlers for the same class (Person) i.e. one synchronous and the other asynchronous? If I put both handler classes in my code, then both the mediator.send lines i.e. mediator.Send(new Person());
and Task.Run(() => mediator.Send(new Person()));
call the synchronous method.
How can I tell mediatr, which handler class to use? i.e. PersonHandler for synchronous calls and PersonHandlerAsync for asynchronous calls.
You can't do it how you've specified.
Declare whatever flavor of handler you need - sync, async or cancellable async. From the IMediator side, the interface is async-only, designed for modern hosts.
However, one workaround would be to create a PersonRequest
and PersonRequestAsync
class, inherited from Person
class:
public class Person
{
public int Id {get; set;}
public string Name {get; set;}
public int Age {get; set;}
}
//sync request
public class PersonRequest : Person, IRequest<Person>
{ }
//async request
public class PersonRequestAsync : Person, IRequest<Person>
{ }
Then, your handlers could look something like this:
public class PersonHandler : IRequestHandler<PersonRequest, Person>
{
public Task<Person> Handle(Person request, CancellationToken cancellationToken)
{
request.ID = 1;
request.Name = "Brian";
request.Age = 53;
return Task.FromResult(request);
}
}
And your async
handler as follows:
public class PersonHandlerAsync : IRequestHandler<PersonRequestAsync, Person>
{
public async Task<Person> Handle(PersonRequestAsync request, CancellationToken cancellationToken)
{
request.ID = 1;
request.Name = "Brian";
request.Age = 53;
//not sure what this is? Hopefully it's just here for demo purposes!
var result = await Task.FromResult(request);
await Task.Delay(30000);
return result;
}
}
This effectively ties PersonRequestAsync
to PersonHandlerAsync