2009/03/31

我自己的框架RhinoLite (二) Unit Of Work

Unit of Work, 工作单元, 这个是本框架的核心部分, 负责配置, 初始化和管理nhibernate的Session, SessionFactory, 所以, 我们第一步从这里开始.

首先, 我们看看这个部分包含了哪些东西.



























通过类图我们可以看到, 我们有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 List BuildFluentConfiguration()
{
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了.

No comments: