Imagine that I have one method like below that is using some strategies to create new products and persists them as a result in the Db.
And everything happens as a part of a Unit of Work.
(My concern and)Question :
My concern is it OK or preventable to pass the UnitOfWork instance as a parameter to strategies and Commit the changes in the root method?
How can I avoid passing the UnitOfWork instance as a parameter to strategies but still make them work as a part of unit of work?
(I don’t like the fact that someone can call .Commit inside strategy implementations by mistake -which I do not want)
public void DoTheJob(CustomerRequest req)
{
var materialsPikcerStrategyFactory = new PickerStrategyFactory();
var productionStrategyFactory = new ProductionStrategyFactory();
var materialsPickerStrategy = materialsPikcerStrategyFactory.GetStrategy(req);
var productionStrategy = productionStrategyFactory.GetStrategy(req);
using (var uow = new UnitOfWorkFactory() )
{
var materials = materialsPickerStrategy.PickMaterials(req, uow);
var products = productionStrategy.CreateProductsWith(materials, uow);
uow.Commit();
}
}
puplic abstract class MaterialsPickerStrategy
{
// Picks some material entities from Db and modifies some of its properties before usage
public abstract ICollection<Material> PickMaterials(CustomerRequest req, IUnitOfWorkFactory uow);
}
public abstract class ProductionStrategy
{
// Gets the materials and creates some new instances by ADD'ing them to the repository
public abstract void CreateProductsWith (ICollection<Material> materials, IUnitOfWorkFactory uow);
}
It seems like your code is using only unit of work but not repositories. They are usually use together to solve your problem. Repository is responsible for fetching data from database or registering changes in current unit of work and unit of work is responsible for committing registered changes. That would allow you passing repositories to your strategies and strategy will not have access to unit of work.
In terms of EF
ObjectContext/DbContextcan be considered as unit of work andObjectSet/DbSetcan be considered as repository. If you have custom unit of work and custom repositories they must all share single EF context instance.