C# 如何使用线程安全实现UnitOfWork、存储库模式、Unity和EF

C# 如何使用线程安全实现UnitOfWork、存储库模式、Unity和EF,c#,multithreading,entity-framework,unity-container,unit-of-work,C#,Multithreading,Entity Framework,Unity Container,Unit Of Work,我是这样想的: IUoW oUoW = oUnity.Resolve<IUoW>(); //<-- New Context here (Life per resolve). var oNewEntity = new SomeEntity{ name = "somethink ... "}; oUoW.oSomeEntity.Add( oNewEntity); oUoW.SaveChanges(); oUoW.Dispose();//<-- delete context

我是这样想的:

IUoW oUoW = oUnity.Resolve<IUoW>(); //<-- New Context here (Life per resolve).
var oNewEntity = new SomeEntity{ name = "somethink ... "};

oUoW.oSomeEntity.Add( oNewEntity);
oUoW.SaveChanges();

oUoW.Dispose();//<-- delete context.

IUoW=oUnity.Resolve()// 一旦您解决了uow,存储库应该是uow的直接属性:

IUoW oUoW = oUnity.Resolve<IUoW>(); //<-- New Context here (Life per resolve).
var oNewEntity = new SomeEntity{ name = "somethink ... "};

oSomeEntityRepository = uow.SomeEntityRepository;//Not ugly at all

@Wiktor Zychla是对的,但我认为他的例子会让你困惑。如果您使用的是DI容器,比如这里的Unity,那么在解析UOW时应该将存储库注入UOW中;一个DBContext实例注入UOW(调用saveChanges)和所有已解析的repositores(我假设您的UOW有多个存储库,因为如果没有,您就不需要UOW)。这被称为“级联注入”,是使用DI容器的黄油和面包


通过这种方式,您可以使用多个存储库(一个用于聚合根)在数据库中进行多个更改,以完成一个用例,并且只需要一个UOW.Savechanges。

我编辑了一个模板,该模板自动生成UnitOfWork、Context、Repository和FactoryUnitOfWork,如果在单独的dll中执行此操作,则需要编辑模板以更改实体模型

要使用该模式,请执行以下操作: 在组合根目录中注册:

IUnityContainer uc = new UnityContainer();
yourdaonamespace.CompositionRoot.Init( uc );
以及使用:

using (var oIUoW = this.IFactoryUnitOfWork.Resolve())
{
    var YOURENTITYFoundedFromRepository = oIUoW.oRepositoryENTITY.First(o => o.iYourProperty == 1);
}

//more code 
using (var oIUoW = this.IFactoryUnitOfWork.Resolve())
{ 
   var entity = new domain.YOURENTITY()
   {
       sYourProperty = "TEST ENTITY"
   };
   uow.oRepositoryYOURENTITY.Insert(entity);
   uow.Commit();
}
要求:您需要生成YOURMODEL.edmx


注意:模板在Pastebin中是临时的,任何人都可以帮助使用永久模板,谢谢

你的申请是什么?网络,服务?知道这一点会很有用。您上面创建的消费代码是每个线程的吗?当然是主题,但为什么在所有代码前面都加上“o”?除了让你的代码在你大声读的时候听起来像鬼魂之外?不必这样。UoW已解决,UoW中的存储库不必解决。我不太同意。具体的uow类型意味着具体的存储库,因此,如果解析uow,就不需要解析存储库。我相信您试图滥用DI,将太多的责任放在DI上,并直接依赖它生成太多的组件。是的,我认为是这样,但以单元测试为例,我希望生成两个UoW,这可能是一个好主意,但灵活性较低,如果我想更改一个存储库的实现,我需要更改UoW实现,而不是组合根。远未实现,但可能是。。。就目前而言,我遵循您的想法,感谢UOW和存储库中的OSE耦合是一个好主意。正如OP所说的,任何实现都会使您接触一个类,因为依赖关系的更改违反了可靠的规则。
public class UnitOfWork
{
     private ISomeEntityRepository _someEntityRepository;
     public ISomeEntityRepository SomeEntityRepository
     {
         get
         {
              if ( _someEntityRepository == null )
                    _someEntityRepository = new ...
              return _someEntityRepository;
         }
IUnityContainer uc = new UnityContainer();
yourdaonamespace.CompositionRoot.Init( uc );
using (var oIUoW = this.IFactoryUnitOfWork.Resolve())
{
    var YOURENTITYFoundedFromRepository = oIUoW.oRepositoryENTITY.First(o => o.iYourProperty == 1);
}

//more code 
using (var oIUoW = this.IFactoryUnitOfWork.Resolve())
{ 
   var entity = new domain.YOURENTITY()
   {
       sYourProperty = "TEST ENTITY"
   };
   uow.oRepositoryYOURENTITY.Insert(entity);
   uow.Commit();
}