静态存储库是使用 NHibernate 的正确方法吗? [英] Is a static repository a right way to use NHibernate?

查看:25
本文介绍了静态存储库是使用 NHibernate 的正确方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了晚上剩下的时间阅读 StackOverflow 问题以及一些有关该主题的博客条目和链接.结果证明他们都非常有帮助,但我仍然觉得他们没有真正回答我的问题.

I spent the rest of the evening reading StackOverflow questions and also some blog entries and links about the subject. All of them turned out to be very helpful, but I still feel that they don't really answer my question.

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

So, I'm developing a simple web application. I'd like to create a reusable data access layer which I can later reuse in other solutions. 99% of these will be web applications. This seems to be a good excuse for me to learn NHibernate and some of the patterns around it.

我的目标如下:

  • 我不希望业务逻辑层了解有关数据库内部工作的任何信息,也不希望 NHibernate 本身.
  • 我希望业务逻辑层对数据访问层有尽可能少的假设.
  • 我希望数据访问层尽可能简单易用.这将是一个简单的项目,所以我不想让任何事情变得过于复杂.
  • 我希望数据访问层尽可能不受干扰.

考虑到所有这些,我决定使用流行的存储库模式.我在此站点和各种开发博客上阅读了有关此主题的内容,并且听说了一些有关工作单元模式的内容.

Will all this in mind, I decided to use the popular repository pattern. I read about this subject on this site and on various dev blogs, and I heard some stuff about the unit of work pattern.

我还环顾四周并检查了各种实现.(包括 FubuMVC contrib 和 SharpArchitecture 以及一些博客上的内容.)我发现其中大部分都以相同的原则运行:它们创建一个工作单元",在实例化存储库时实例化,然后启动事务,做一些事情,并提交,然后重新开始.因此,每个 Repository 只有一个 ISession,仅此而已.然后客户端代码需要实例化一个存储库,用它做一些事情,然后处理.

I also looked around and checked out various implementations. (Including FubuMVC contrib, and SharpArchitecture, and stuff on some blogs.) I found out that most of these operate with the same principle: They create a "unit of work" which is instantiated when a repository is instantiated, they start a transaction, do stuff, and commit, and then start all over again. So, only one ISession per Repository and that's it. Then the client code needs to instantiate a repository, do stuff with it, and then dispose.

这种使用模式不符合我尽可能简单的需求,所以我开始考虑别的.

This usage pattern doesn't meet my need of being as simplistic as possible, so I began thinking about something else.

我发现 NHibernate 已经有了一些使自定义工作单元"实现变得不必要的东西,那就是 CurrentSessionContext 类.如果我正确配置了会话上下文,并在必要时进行了清理,我就可以开始了.

I found out that NHibernate already has something which makes custom "unit of work" implementations unnecessary, and that is the CurrentSessionContext class. If I configure the session context correctly, and do the clean up when necessary, I'm good to go.

所以,我想出了这个:

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

I have an internal static class called NHibernateHelper. Firstly, it has a static property called CurrentSessionFactory, which upon first call, instantiates a session factory and stores it in a static field. (One ISessionFactory per one AppDomain is good enough.) Then, more importantly, it has a CurrentSession static property, which checks if there is an ISession bound to the current session context, and if not, creates one, and binds it, and it returns with the ISession bound to the current session context.

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

Because it will be used mostly with WebSessionContext (so, one ISession per HttpRequest, although for the unit tests, I configured ThreadStaticSessionContext), it should work seamlessly. And after creating and binding an ISession, it hooks an event handler to the HttpContext.Current.ApplicationInstance.EndRequest event, which takes care of cleaning up the ISession after the request ends. (Of course, it only does this if it is really running in a web environment.)

因此,通过所有这些设置,NHibernateHelper 将始终能够返回有效的 ISession,因此无需为工作单元"来正常运行.相反,Repository 是一个静态类,它使用 NHibernateHelper.CurrentSession 属性中的 ISession 操作,并通过通用方法通过它公开功能.

So, with all this set up, the NHibernateHelper will always be able to return a valid ISession, so there is no need to instantiate a Repository instance for the "unit of work" to operate properly. Instead, the Repository is a static class which operates with the ISession from the NHibernateHelper.CurrentSession property, and exposes functionality through that by generic methods.

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

So, basically, I ended up with two very lazy singletons.

我很好奇,你怎么看这个?这是一种有效的思维方式,还是我完全偏离了轨道?

I'm curious, what do you think about this? Is it a valid way of thinking, or am I completely off track here?


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


I must point out that the NHibernateHelper class is internal, so pretty much invisible to the consumers of the repository.

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

Another idea is, in order to intoduce dependency injection into the solution, is to make an interface named IDataProvider, and instantiate one instance of that upon the first call to the Repository class. (However, the implementing code should be able to take care the concept of context also.)

编辑 2:
貌似很多人都喜欢我的想法,但是答案里对它的看法还是太少了.
我可以假设这是使用 NHibernate 的正确方法吗?:P

EDIT 2:
It seems that many people like my idea, but there are still too few opinions about it in the answers.
Can I assume that this is a right way to use NHibernate, then? :P

推荐答案

就其价值而言,Sharp Architecture 或多或少地完全按照您的建议去做.它最终为每个 HTTP 请求提供一个会话(更准确地说,每个 HTTP 请求每个数据库一个会话).您的方法当然是有效的,并且每个请求也提供一个会话.我更喜欢 SharpArch 通过 DI 的更清晰的 OO 方法,而不是使用静态存储库和帮助程序类.

For what it is worth, Sharp Architecture is doing more or less exactly what you are suggesting. It ends up delivering one session per HTTP request (more accurately, one session per database per HTTP request). Your approach is certainly valid and also delivers one session per request. I rather prefer SharpArch's cleaner OO approach via DI over using static repositories and the helper class.

这篇关于静态存储库是使用 NHibernate 的正确方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆