为什么我要在 NHibernate 会话之上使用工作单元模式?
-
13-09-2019 - |
题
我什么时候会在 NHibernate 已经提供的基础上编写 UoW 实现?有现实世界的例子吗?
解决方案
您所描述的工作单元已经由 NHibernate 提供,因此没有理由执行这样的工作单元。
我们在 WCF 服务中拥有的是更高级别的工作单元,其中包含对我们当前工作单元的应用程序很重要的信息。这包括为我们抽象 NHibernate ISession。当你分解它时,你会得到适合三类的代码
需要处理工作单元的代码。谁支持工作单元并不重要。它可以是 NHibernate、iBatis 或自定义 ORM。所有代码需要做的就是加载、回滚、保存等。它不也不应该关心用于执行此操作的机制。
需要直接处理 ISession 的代码,因为它正在执行 NHibernate 特定的操作。通常这与需要创建的复杂查询有关。
不需要知道它正在工作单元中运行或访问 ISession。作为讨论的一部分,我们可以完全忽略这一点。
虽然代码在 1 中。可以只针对 ISession 我们的偏好是尝试抽象出代码中我们无法直接控制或可能更改的内容。其价值有两个原因。
当我们开始时,我们并没有 100% 相信 NHibernate。我们正在考虑 iBatis 或定制的东西。显然这不再是问题。
整个团队都不是 NHibernate 专家,我们也不希望他们成为专家。大多数情况下,人们编写的代码都属于第一类。他们只知道我们的工作单元。当代码处于类别 2 时。必须由团队中熟悉 NHibernate 的人员编写。
因此,最后我想说的是,您所讨论的工作单元类型是不需要的,我建议更高级别的工作单元可以提供很多价值。
其他提示
我的工作接口的基本单元包含下列方法 - 初始化 - 提交 - 回滚 - IDisposable.Dispose
我用它了会话和事务管理。 因为我没有一次又一次地编写代码,不同的会话范围是非常有用的。 (每请求工作的单元中,每系列的请求,每个线程等)
只要你设置了所有正确的映射(即级联),你没有做什么特别和ISession
会做得很好。但是,如果你正在写一个3层应用程序,你必须要在一个事务中进行手动序列数据库操作。在“企业应用架构模式”福勒的“参考实现”可以是一个很好的起点:
class UnitOfWork...
public void registerNew(DomainObject obj) {
Assert.notNull("id not null", obj.getId());
Assert.isTrue("object not dirty", !dirtyObjects.contains(obj));
Assert.isTrue("object not removed", !removedObjects.contains(obj));
Assert.isTrue("object not already registered new", !newObjects.contains(obj));
newObjects.add(obj);
}
public void registerDirty(DomainObject obj) {
Assert.notNull("id not null", obj.getId());
Assert.isTrue("object not removed", !removedObjects.contains(obj));
if (!dirtyObjects.contains(obj) && !newObjects.contains(obj)) {
dirtyObjects.add(obj);
}
}
public void registerRemoved(DomainObject obj) {
Assert.notNull("id not null", obj.getId());
if (newObjects.remove(obj)) return;
dirtyObjects.remove(obj);
if (!removedObjects.contains(obj)) {
removedObjects.add(obj);
}
}
public void registerClean(DomainObject obj) {
Assert.notNull("id not null", obj.getId());
}