I am developing an app which uses Entity Framework for data access. The architecture of the app somewhat like below:
As depicted in the drawing, the business service can be consumed from either web app, cli app or windows service. What I'm trying to design is, each service request should be performed in a single transaction. I'm using dependency injection to inject services to web api controllers. If I use request scoped dbcontext using DI container, it'll do the job for web api, but won't work for service requests coming directly from CLI app or windows services.
What are best practices used to handle service level transactions with Entity Framework?
e.g.
// Services
public class UserService
{
private TaskService _taskService;
private UserRepository _userRepository;
public UserService(TaskService taskService, UserRepository userRepository)
{
this._taskService = taskService;
this._userRepository = userRepository;
}
public void MarkInactive(int userId)
{
this._taskService.CloseAllPendingTasks(userId);
this._userRepository.MarkInactive(userId);
}
}
public class TaskService
{
public void CloseAllPendingTasks(int userId)
{
...
}
}
// Consumer
// Scenario 1:
this._taskService.CloseAllPendingTasks(1);
// Scenario 2:
this._userService.MarkInactive(2);
In above example, In case of Scenario 1
, task service should create new transaction for the operation. While in Scenario 2
, user service should create a transaction and task service should join the already open transaction.
If I use request scoped dbcontext using DI container, it'll do the job for web api, but won't work for service requests coming directly from CLI app or windows services.
-- Why?While in Scenario 2, user service should create a transaction and task service should join the already open transaction.
-- Why?RequestContext
to work properly.In scenario 2, I would want both those operations (changing user's status and closing their pending tasks) to be done in a single atomic transaction.
-- Then provide a single service method that performs both tasks.