Trying to use an async method as I used to do with Repository Pattern to post an entity, but this time I wanted to integrate the Unit Of Work pattern, here is my interface:
public interface IUnitOfWork : IDisposable
{
. . .
void Save();
}
And its implementation:
public class UnitOfWork : IUnitOfWork
{
private readonly DataContext _db;
public UnitOfWork(DataContext db)
{
_db = db;
. . .
}
. . .
public void Dispose()
{
_db.Dispose();
}
public void Save()
{
_db.SaveChanges();
}
}
And here is my method:
[HttpPost]
public async Task<IActionResult> CreateItem(string userId, ItemForCreationDto itemForCreationDto)
{
if (userId != User.FindFirst(ClaimTypes.NameIdentifier).Value)
return Unauthorized();
itemForCreationDto.UserId = userId;
var item = _mapper.Map<Item>(itemForCreationDto);
if (item == null)
return BadRequest("Could not find item");
_uow.Item.Add(item);
if (await _uow.Save()) <--- Error here
{
var itemToReturn = _mapper.Map<ItemToReturnDto>(item);
return CreatedAtRoute("GetItem",
new { userId, id = item.Id }, itemToReturn);
}
throw new Exception("Creating the item failed on save");
}
But I got the following erors:
Can't wait for 'void'
That's because I am trying to call a Save() method which is void from an async HttpPost method, I know that makes no sens, but till now I could not find how to implement that for this special case. When I tried removing the await I got the following error:
Unable to implicitly convert type 'void' to 'bool'
Any suggestion on how to implement that ?
Either refactor the interface to be async or add an additional member
public interface IUnitOfWork : IDisposable {
//. . .
Task<bool> SaveAsync();
}
that can probably wraps the context's asynchronous API in the implementation if one exists
public async Task<bool> SaveAsync() {
int count = await _db.SaveChangesAsync();
return count > 0;
}
allowing for the desired functionality
//...
if (await _uow.SaveAsync()){
var itemToReturn = _mapper.Map<ItemToReturnDto>(item);
return CreatedAtRoute("GetItem", new { userId, id = item.Id }, itemToReturn);
}
//...