使用仓储模式与NHibernate的最佳方式是什么?

8

我有一个存储库类,定义了一些基本的Get/Save/Delete方法。在这些方法内部,我使用NHibernate对我的业务实体进行操作。例如:

Public Class SecurityRepositoryNHibImpl : Implements ISecurityRepository
    Public Function GetUser(ByVal UUID As System.Guid) As Entities.User Implements ISecurityRepository.GetUser
        Dim eUser As Entities.User
        Using session As ISession = NHibernateHelper.OpenSession()
            eUser = session.Get(Of Entities.User)(UUID)
        End Using
        Return eUser
    End Function
End Class

然而,在我的用户类上,我有一些其他对象的属性和集合,最好是惰性加载。但当然,ISession在存储库内创建和处理,这也许就是为什么在外部尝试访问这些属性时会出现“无法初始化代理-没有会话”的错误的原因。
那么,当使用存储库时,我的唯一选择是禁用延迟加载吗?还是可能(或只是愚蠢)以某种方式将会话引入业务层范围内?
我喜欢存储库模型,并且NHibernate正在逐渐发展(经过大量最初的挫败后),那么您这些大师们发现一起使用它们的最佳方法是什么?
我对NHibernate和存储库模型都很陌生(在工作中,我们仍然主要使用VB6!),所以请原谅可能是一个愚蠢的问题。谢谢。

@mookid:谢谢,这真的很有帮助,但我可能会让它保持开放更长一些。它是 WCF web 服务的后端,并且所有函数都将是按调用上下文,因此按调用周期的会话生命周期将是不错的选择。只是不确定如何在业务层中实现这样的功能,理想情况下,我不希望业务对象直接与任何 NHibernate 类接口。我猜至少需要对 NHibernate 会话进行某种包装以将其抽象化... 嗯,你至少让我找到了正确的方向。


看起来这里的关键词是“工作单元”,与NHibernate相关的网络资源非常丰富。特别是要查找Rhino Commons中Ayende的实现,以及他在Hibernating Rhinos的应用架构网络研讨会(编号9),非常有启发性。最初我感到困惑,因为我认为将“工作单元”放在业务层中会混淆问题,但很快就被纠正了。

1个回答

12

在小型和非常简单的项目中,像这样明确创建您的ISession并在存储库内显式释放它是可以的 - 但是,正如您发现的那样,当您开始想要使用NHibernate支持的一些很酷的功能时,它会有所不足。

您应该让会话的生命周期由存储库之外的某些东西来控制 - 例如,如果您正在进行ASP.NET Web应用程序,则可能希望在Web请求期间保存会话(如果我记得正确,则为HttpContext.Current.Items),然后在请求结束时提交和释放(或在发生异常时回滚)。

我不知道在ASP.NET应用程序中控制会话生命周期的最佳方法是什么,但必须有一些方法可以在每个请求的开始和结束时调用代码。在ASP.NET MVC中,通过使所有的控制器派生自一个基础控制器,并覆盖其OnActionExecutingOnActionExecuted方法,可以轻松地实现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接