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();
}