After saving the record to the database, I need to get the Id that will be returned from my Domain layer. For this I am using the features of the MediaTr library.
public class PessoaCommandHandler : CommandHandler,
IRequestHandler<RegisterNewPessoaCommand, int>,
IRequestHandler<UpdatePessoaCommand, int>,
IRequestHandler<RemovePessoaCommand, int>
{
private readonly IPessoaRepository _pessoaRepository;
private bool _allowEndTransaction;
private readonly IMediatorHandler Bus;
public PessoaCommandHandler(IPessoaRepository pessoaRepository,
IUnitOfWork uow,
IMediatorHandler bus,
INotificationHandler<DomainNotification> notifications) : base(uow, bus, notifications)
{
_pessoaRepository = pessoaRepository;
_allowEndTransaction = true;
Bus = bus;
}
public Task<int> Handle(RegisterNewPessoaCommand message, CancellationToken cancellationToken)
{
if (!message.IsValid())
{
NotifyValidationErrors(message);
return Task.FromResult(0);
}
var pessoaModel = new Pessoa(message.PessoaNatureza);
_pessoaRepository.Add(pessoaModel);
return Task.FromResult(pessoaModel.Id);
}
}
Now, let's get to the problem: I need to take the integer value that is in the "Result" property and put it into the personId variable, but I don't know how to do that. Does anyone know how to do this?
public void Register(PessoaViewModel pessoaViewModel)
{
var registerCommand = _mapper.Map<RegisterNewPessoaCommand>(pessoaViewModel);
var pessoaId = Bus.SendCommand(registerCommand);
}
Probably the easiest way to unwrap the value returned by a Task
would be to use async
/await
.
Though, you'll want to shy away from async void
methods where possible as this results in a "fire and forget" method that cannot be awaited (this will potentially turn into a debugging nightmare as any exceptions will be lost to the void, etc.) -- so let's have the Register method return a Task
instead:
async public Task Register(PessoaViewModel pessoaViewModel)
{
var registerCommand = _mapper.Map<RegisterNewPessoaCommand>(pessoaViewModel);
var pessoaId = await Bus.SendCommand(registerCommand);
// use `pessoaId` as needed
}
If for some reason async
/await
is unavailable, the following option is also possible (though, note that this option is synchronous and will block current thread execution, etc.):
public void Register(PessoaViewModel pessoaViewModel)
{
var registerCommand = _mapper.Map<RegisterNewPessoaCommand>(pessoaViewModel);
var pessoaId = Bus.SendCommand(registerCommand).GetAwaiter().GetResult();
// use `pessoaId` as needed
}
For completeness, I'll add that it would also be possible to use Bus.SendCommand(registerCommand).Result;
but this is generally considered bad practice as it will obfuscate any exceptions inside of an aggregate exception, etc.
Also, here's a solid answer to a similar question about how the unwrapping occurs.