Cześć, mam taki problem.
Mam kontroler, który obsługuje operacje na użytkownikach. Wszystkie operacje są realizowane przez UserManager. W pewnym momencie muszę użyć transakcji (zmiana hasła polegająca na usunięciu hasła i dodaniu nowego). I tu pojawia się pewien problem architektoniczny. Ponieważ, żeby użyć transakcji w operacjach na użytkowniku, muszę do klasy kontrolera wstrzyknąć ApplicationDbContext. W tym miejscu uzależniam cały kontroler od bazy danych i EntityFramework. Co za tym idzie - testy kontrolera wydają się być niemożliwe (ewentualnie muszę zmieniać kod pod testy).
Jak sobie z tym poradzić? Fragment kodu:\
public class UsersController : ControllerBase
{
UserManager<ApplicationUser> userManager;
ApplicationDbContext dbContext;
public UsersController(UserManager<ApplicationUser> userManager, ApplicationDbContext dbContext)
{
this.userManager = userManager;
this.dbContext = dbContext;
}
public async Task<IActionResult> JakasMetoda()
{
using(var transaction = dbContext.Database.BeginTransaction())
{
//...
transaction.Commit();
}
}
Jeden pomysł, jaki mi się nasuwa, to stworzyć sobie taki interfejs:
public interface ITransactionManager
{
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
}
I jego wstrzykiwać. Na podstawie tego interfejsu tworzę sobie klasę, której wstrzykuję ApplicationDbContext i drugą, która ma puste implementacje - do testów.
Jednak to powoduje problem taki, że nie będę miał zwróconej transakcji. Mógłbym to próbować jakoś obejść, ale czy to dobra droga?