Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我是否应该也可以避免通过方法将UnitOfWork实例传递给策略?_C#_.net_Entity Framework_Design Patterns_Unit Of Work - Fatal编程技术网

C# 我是否应该也可以避免通过方法将UnitOfWork实例传递给策略?

C# 我是否应该也可以避免通过方法将UnitOfWork实例传递给策略?,c#,.net,entity-framework,design-patterns,unit-of-work,C#,.net,Entity Framework,Design Patterns,Unit Of Work,想象一下,我有一种方法,如下面所示,它使用一些策略来创建新产品,并将它们作为结果保存在数据库中 每件事都是作为一个工作单元的一部分发生的 (我的担忧和)问题: 我关心的是,将UnitOfWork实例作为参数传递给strategies并提交根方法中的更改是否可以或可以预防? 如何避免将UnitOfWork实例作为参数传递给策略,但仍然使它们作为工作单元的一部分工作 (我不喜欢有人会错误地调用.Commit内部策略实现——我不希望这样) public void DoTheJob(CustomerRe

想象一下,我有一种方法,如下面所示,它使用一些策略来创建新产品,并将它们作为结果保存在数据库中

每件事都是作为一个工作单元的一部分发生的

(我的担忧和)问题: 我关心的是,将UnitOfWork实例作为参数传递给strategies并提交根方法中的更改是否可以或可以预防? 如何避免将UnitOfWork实例作为参数传递给策略,但仍然使它们作为工作单元的一部分工作

(我不喜欢有人会错误地调用.Commit内部策略实现——我不希望这样)

public void DoTheJob(CustomerRequest请求)
{
var materialsPikcerStrategyFactory=新PickerStrategyFactory();
var productionStrategyFactory=新的productionStrategyFactory();
var materialsPickerStrategy=materialsPikcerStrategyFactory.GetStrategy(需求);
var productionStrategy=productionStrategyFactory.GetStrategy(req);
使用(var uow=new UnitOfWorkFactory())
{
var物料=物料分拣策略分拣物料(需求,uow);
var products=productionStrategy.CreateProductsWith(物料,uow);
提交();
}
}
puplic抽象类MaterialsPickerStrategy
{
//从Db中拾取一些材质实体,并在使用前修改其某些属性
公共摘要I收集材料(客户请求,IUnitOfWorkFactory uow);
}
公共抽象类生成策略
{
//获取材质并通过将其添加到存储库来创建一些新实例
创建产品的公开摘要无效(i收集材料,i工厂uow);
}

我会将一个UnitOfWork作为依赖项传递给执行提交所需的任何类,我理解,在您的情况下,如果您不想成为您的策略的话

UnitOfWork应该知道如何提交更新,因为它会引用某种数据上下文。可能还有实体框架模型、DBContext等

如果你的策略不应该承诺,你就不应该知道工作单元。我猜您可能使用UnitOfWork将您的数据上下文公开给您的策略

您的策略和UnitOfWork都应该引用相同的数据上下文。然后,您的策略与上下文和其他一些例程一起工作,它可能使用了许多策略,最后会引用UnitOfWork来提交它


如果您使用的是IOC框架,这是非常直接的,因为您将数据上下文的生存期范围指定为PerRequest,并将其作为依赖项传递给两个类。当框架将依赖注入到类中时,它将使用相同的实例,因此您的策略将写入工作单元持有的相同实例。通过这种方式,您通过策略对数据所做的更改与工作单元将要提交的更改相同。如果你对IOC非常熟练,你实际上可以注入给定类所需的上下文的各个部分,进一步隔离依赖关系。

你的代码似乎只使用工作单元,而不使用存储库。它们通常一起用来解决你的问题。存储库负责从数据库获取数据或注册当前工作单元中的更改,而工作单元负责提交已注册的更改。这将允许您将存储库传递给策略,而策略将无法访问工作单元


就EF而言,
ObjectContext
/
DbContext
可以被视为工作单元,
ObjectSet
/
DbSet
可以被视为存储库。如果您有自定义工作单元和自定义存储库,它们必须共享单个EF上下文实例

因此,我可以传递存储库,这些存储库是我使用的UnitOfWork的属性,而不是paassing UnitOfWork。比如uow.MaterialsRepository
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);
}