总体概览
一个非常高层次的NHibernate架构:
这个图展示了NHibernate使用数据库和配置信息来为应用程序提供持久化服务(和持久化对象)。
我们想展示一个更加详细的运行时架构。但是NHibernate 很灵活并且支持多种架构方式。我们将会展示两个极端。对于“轻量级”架构,应用程序管理自身的ADO.NET连接和事务。这个方式仅仅使用了很小的一部分NHibernate API:
对于“重量级”架构,它将应用程序的ADO.NET抽象出来,然后使用NHibernate 管理其中的细节。
-
-
-
-
以下是图中一些对象的定义:
- ISessionFactory (NHibernate.ISessionFactory)
-
一个线程安全(不变的)的单数据库mapping缓存。ISession 的制造工厂和IConnectionProvider 的消费者。可能拥有一个自定义的(二级)在处理器集群水平下的(processor cluster-level)事务之间可重用数据缓存。
- ISession (NHibernate.ISession)
-
生命周期短暂的单线程的对象,表示应用程序和数据库之间的会话。包含一个ADO.NET连接,是ITransaction的工厂。
-
-
拥有一个强制的(一级)持久化对象缓存,在查询对象图谱或者通过标识符查询对象的时候提供缓存。
- Persistent Objects and Collections
-
-
-
-
生命周期短暂的单线程的对象,包含持久化状态和业务方法。他们可能是普通的POCO,唯一不同之处在于他们和(一个)ISession关联。只要这个Session 关闭了,他们就会变成detached 状态,并且可以在任何应用层无障碍使用(例如,直接作为展示层的DTO)。
Transient Objects and Collections
-
持久化类的实例,不和ISession 关联。他们可能已经被应用程序实例化,并且(还)没有持久化或者是已经被一个关闭的ISession实例化。
- ITransaction (NHibernate.ITransaction)
-
(可选的)生命周期短暂的单线程的对象,作为原子的工作单元(atomic units of work)被用在应用程序中。将应用程序从相应的ADO.NET 事务抽象出来。在某些情况下,一个ISession 可能横穿多个ITransactions 。
- IConnectionProvider (NHibernate.Connection.IConnectionProvider)
- (可选的)一个ADO.NET 连接和命令工厂。将应用程序特定(数据库)供应商实现的IDbConnection 和IDbCommand 抽象出来。不暴露给应用程序,但是可以被开发者扩展或者实现。
- IDriver (NHibernate.Driver.IDriver)
- (可选的)一个包含各个ADO.NET提供者的不同配置的接口,例如各自的参数命名惯例和支持的ADO.NET 特征。
- ITransactionFactory (NHibernate.Transaction.ITransactionFactory)
- (可选的)一个ITransaction 实例的工厂。不暴露给应用程序,但是可以被开发者扩展或者实现。
-
-
在“轻量级”的架构中,应用程序绕过所有ITransaction/ITransactionFactory 和 IConnectionProvider ,直接与ADO.NET 交互。
实例状态
根据持久化上下文(persistence context)的定义,一个持久化类可能有三个状态中的一个。NHibernate ISession 是持久化上下文:
- 瞬时态(transient)
-
这个实例没有,并且永远从来没有和持久化上下文有关联。它没有持久化标识符(主键)。
- 持久态(persistent)
-
这个实例和一个持久化上下文关联。它有一个持久化标识符(主键),也许,在数据库中也有对应的记录。对于一个特定的持久化上下文,NHibernate 能保证持久化对象identity和CLR identity一致(对象在内存中的位置)。
- 游离态(detached)
-
这个实例曾经和一个持久化上下文关联,但是上下文已经关闭或者实例已经被序列化到其他进程中。它有一个持久化标识符,也许,在数据库中也有对应的记录。对于游离态的实例,NHibernate 不能保证持久化对象identity和CLR identity一致。
上下文会话
Most applications using NHibernate need some form of "contextual" sessions, where a given session is in effect throughout the scope of a given context. However, across applications the definition of what constitutes a context is typically different; and different contexts define different scopes to the notion of current.
大多数使用NHibernate的应用程序需要一些“上下文的”会话形式,在这个上下文中会话是有效的。然而,从整个应用程序来看,上下文的组成是不同的;并且不同的上下文定义了不同的scopes to the notion of current.
从1.2版本起,NHibernate添加了 ISessionFactory.GetCurrentSession() 方法。ISessionFactory.GetCurrentSession() 背后的处理方式是可拔插的。添加了一个扩展的接口(NHibernate.Context.ICurrentSessionContext) 和一个新的配置参数(hibernate.current_session_context_class) 以支持可拔插性。
通过查看API文档来获得NHibernate.Context.ICurrentSessionContext 接口的相关详情。它定义了一个方法,CurrentSession(),这个实现通过这个方法来负责追踪当前上下文会话。NHibernate提供了一些立即可用的接口的实现:
Starting with version 1.2, NHibernate added the ISessionFactory.GetCurrentSession() method. The processing behind ISessionFactory.GetCurrentSession() is pluggable. An extension interface (NHibernate.Context.ICurrentSessionContext) and a new configuration parameter (hibernate.current_session_context_class) have been added to allow pluggability of the scope and context of defining current sessions.
See the API documentation for the NHibernate.Context.ICurrentSessionContext interface for a detailed discussion of its contract. It defines a single method, CurrentSession(), by which the implementation is responsible for tracking the current contextual session. Out-of-the-box, NHibernate comes with several implementations of this interface:
NHibernate.Context.CallSessionContext - current sessions are tracked by CallContext. You are responsible to bind and unbind an ISession instance with static methods of class CurrentSessionContext .
NHibernate.Context.ThreadStaticSessionContext - current session is stored in a thread-static variable. This context only supports one session factory. You are responsible to bind and unbind an ISession instance with static methods of class CurrentSessionContext.
NHibernate.Context.WebSessionContext - stores the current session in HttpContext. You are responsible to bind and unbind an ISession instance with static methods of class CurrentSessionContext.
NHibernate.Context.WcfOperationSessionContext - current sessions are tracked by WCF OperationContext. You need to register the WcfStateExtension extension in WCF. You are responsible to bind and unbind an ISession instance with static methods of class CurrentSessionContext.
-
NHibernate.Context.ManagedWebSessionContext - current sessions are tracked by HttpContext. Removed in NHibernate 4.0 - NHibernate.Context.WebSessionContext should be used instead. You are responsible to bind and unbind an ISession instance with static methods on this class, it never opens, flushes, or closes an ISession itself.
The hibernate.current_session_context_class configuration parameter defines which NHibernate.Context.ICurrentSessionContext implementation should be used. Typically, the value of this parameter would just name the implementation class to use (including the assembly name); for the out-of-the-box implementations, however, there are corresponding short names: "call", "thread_static", "web" and "wcf_operation", respectively.