首先, 我们看看这个部分包含了哪些东西.
通过类图我们可以看到, 我们有IUnitOfWork和IUnitOfWorkFactory, 前者掌管了Session, 所有的session的获取和dispose都由它负责. 在系统开发中, 需要开启事务等等也是可以由它来完成.
一般来说, 我们一般在一个操作之前创建一个UnitOfWork, 操作结束之后再dispose, 比如我们常见的web开发, 我们一般在beginrequest的时候创建, 在endrequest的时候dispose掉, 这就是所谓的 open-session-in-view模式, 使用这种模式能够方便地使用延迟加载, 简化session管理.
IUnitOfWorkFactory 很简单, 就是用来实例化IUnitOfWork的.
rhinolite 提供了UnitOfWork类, 简化Start, Dispose UnitOfWork, 初始化框架的操作.
ISessionFactoryManager 是对SessionFactory进行管理的类, 他也负责初始化nhibernate.
INHibernateInitializationAware 实现一些在初始化nhibernate过程中需要额外控制的部分, 这个用处很大, 后面大量的功能就是靠它实现
下面是UnitOfWork的序列图.
在nhibernate的配置和初始化, 我们采用了fluent nhibernate, 从而避免了繁琐的xml.
public virtual void InitializeRhinoLite()
{
RhinoLiteInitializer.Configure()
//.WithAutoLogging(@"..\..\log4net.config")
//.WithAutoTransaction()
.WithValidation()
.WithAuditSupport()
.UseNHibernate(f => f.ConfigureFlunetConfigureType())
.RegistServiceFrom();
}
public class FluentConfigurationProvider : IFluentConfigurationProvider
{
public ListBuildFluentConfiguration()
{
var cfg = new Configuration();
var fluentConfiguration = Fluently.Configure(cfg)
.Database(MsSqlConfiguration
.MsSql2005
.ConnectionString(c =>
c.FromConnectionStringWithKey("TestConnection")
)
//because we want to execute sql to get dataset, we must use the extension driver.
//.Driver("RhinoLite.Common.Drivers.ExtSqlClientDriver,RhinoLite.Common")
.Driver()
.ShowSql()
.AdoNetBatchSize(100)
.QuerySubstitutions("true 1, false 0, yes 'Y', no 'N'")
)
.Mappings(m =>
m.HbmMappings.AddFromAssemblyOf() // use xml mappings here.
//m.FluentMappings.AddFromAssemblyOf()
//.AlterConventions(GetConventions)
);
return new List() { new CfgItem(cfg, fluentConfiguration) };
}
}
可以看到, 我们完全避免了hibernate.cfg.xml, 取而代之的是相对优美的fluent api, 这样做有几大好处, 便于测试, 最开始的版本我的配置信息基本都是用配置文件实现的(因为大量使用了castle的IoC), 现在我用简单的fluent api将其封装, 现在基本没有xml了.