静态存储库是使用NHibernate的正确方法吗?

时间:2010-04-26 22:28:56

标签: .net asp.net nhibernate orm repository-pattern

我在晚上的剩余时间里阅读了StackOverflow问题以及一些关于该主题的博客条目和链接。所有这些都证明是非常有帮助的,但我仍然觉得他们并没有真正回答我的问题。

所以,我正在开发一个简单的Web应用程序。我想创建一个可重用的数据访问层,稍后我可以在其他解决方案中重用它。其中99%将是Web应用程序。这似乎是我学习NHibernate及其周围模式的一个很好的借口。

我的目标如下:

  • 我不希望业务逻辑层知道关于数据库内部工作的任何内容,也不希望知道NHibernate本身。
  • 我希望业务逻辑层对数据访问层的假设数量尽可能少。
  • 我希望数据访问层尽可能简单易用。这将是一个简单的项目,所以我不想过度复杂化。
  • 我希望数据访问层尽可能不具有侵入性。

考虑到这一切,我决定使用流行的存储库模式。我在这个网站和各种开发博客上阅读了这个主题,我听到了一些关于工作单元模式的内容。

我也环顾四周,检查了各种实现。 (包括FubuMVC contrib,SharpArchitecture,以及一些博客上的内容。)我发现大多数这些操作都遵循相同的原则:它们创建了一个“工作单元”,在实例化存储库时实例化,它们启动一个事务,做东西,提交,然后重新开始。因此,每ISession只有一个Repository,就是这样。然后客户端代码需要实例化一个存储库,用它做一些事情然后处理。

这种使用模式不符合我尽可能简单化的需要,所以我开始考虑别的事情。

我发现NHibernate已经有了使自定义“工作单元”实现变得不必要的东西,那就是CurrentSessionContext类。如果我正确配置会话上下文,并在必要时进行清理,我很高兴。

所以,我想出了这个:

我有一个名为NHibernateHelper的内部静态类。首先,它有一个名为CurrentSessionFactory的静态属性,在第一次调用时,实例化会话工厂并将其存储在静态字段中。 (每ISessionFactory一个AppDomain就足够了。)然后,更重要的是,它具有CurrentSession静态属性,用于检查当前是否绑定了ISession会话上下文,如果没有,则创建一个并绑定它,并返回绑定到当前会话上下文的ISession

因为它主要用于WebSessionContext(因此,每个ISession一个HttpRequest,但对于单元测试,我配置了ThreadStaticSessionContext),它应该无缝地工作。在创建并绑定ISession之后,它会将事件处理程序挂钩到HttpContext.Current.ApplicationInstance.EndRequest事件,该事件在请求结束后负责清理ISession。 (当然,只有当它真正在Web环境中运行时才会这样做。)

因此,通过所有这些设置,NHibernateHelper将始终能够返回有效的ISession,因此无需为“工作单元”实例化存储库实例正常。相反,Repository是一个静态类,它使用ISession属性中的NHibernateHelper.CurrentSession进行操作,并通过泛型方法公开功能。

所以,基本上,我最终得到了两个非常懒惰的单身人士。

我很好奇,你怎么看待这个? 这是一种有效的思考方式,还是我完全偏离这里?

修改
我必须指出NHibernateHelper类是内部的,因此对于存储库的使用者来说几乎是不可见的。

另一个想法是,为了将依赖注入引入解决方案,是创建一个名为IDataProvider的接口,并在第一次调用Repository类时实例化该实例。 (但是,实现代码也应该能够关注上下文的概念。)

编辑2:
似乎很多人都喜欢我的想法,但在答案中对它的看法仍然太少 我可以假设这是使用NHibernate的正确方法吗? :P

2 个答案:

答案 0 :(得分:2)

对于它的价值,夏普建筑正在或多或少地完全按照你的建议行事。它最终为每个HTTP请求提供一个会话(更准确地说,每个HTTP请求每个数据库一个会话)。您的方法肯定是有效的,并且每个请求也提供一个会话。我更喜欢SharpArch更清洁的OO方法,通过DI使用静态存储库和辅助类。

答案 1 :(得分:1)

我们混合了ASP.NET / Windows Forms应用程序,我发现最好的解决方案是通过存储库构造函数进行手动依赖注入。也就是说,每个存储库类都有一个需要ISession的公共构造函数。这允许应用程序完全控制工作单元和事务边界。它简单而有效。我还有一个非常小的NHibernate助手程序集,它配置会话工厂并提供打开常规或上下文会话的方法。

关于S#arp架构我有很多喜欢的东西,我认为值得研究它是如何工作的,但我发现它的架构过于符合我的口味。

相关问题