Spring.Net+NHibernate 不再使用 XML 描述实体关系
个人对Spring 在java平台下的运用比较熟悉。并且已经是一年前了。
重拾Spring,但选择的是 Spring.Net 。
Java 平台下 Spring+Hibernate 是公认的黄金组合。
.NET 平台下 Spring.Net+NHibernate 也是企业架构最有前途的组合之一。
早前使用Hibernate 比较烦人的就是 编写实体关系映射的 XML 描述文件。
后来在Hibernate 3 以后就开始不再使用XML 改用 Annotation 注解,有点类似 Attributes 的方式。
同样 NHibernate 也有类似 Annotation 的实现。
在NHibernateContrib 项目下有一个子集 NHibernate.Mapping.Attributes 它可以使得我们不在编写XML 。
我在使用 Spring.Net+NHibernate 时发现 Spring.Net IOC 容器在创建 NHibernateSessionFactory
的时候只支持从程序集读取XML来加载对象映射关系,使得我们无法直接使用 Attributes。
解决办法
自定义一个 类 继承自 Spring.Data.NHibernate.LocalSessionFactoryObject
重写 父类的 AfterPropertiesSet() 方法
具体实现代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Reflection; using NHibernate.Mapping.Attributes; namespace Dao.RepositoryDao { public class MyLocalSessionFactoryObject : Spring.Data.NHibernate.LocalSessionFactoryObject { public MyLocalSessionFactoryObject() { } /// <summary> /// 实体类所在程序集的名称 /// </summary> public string[] ModelAssemblyNames { get; set; } /// <summary> /// 将实体类所配置的Attributes转换成XML流添加至Configuration /// </summary> private void AddInputStream() { MemoryStream stream = new MemoryStream(); NHibernate.Mapping.Attributes.HbmSerializer.Default.Validate = true; foreach (string modelAssemblyName in ModelAssemblyNames) { Assembly assembly = Assembly.Load(modelAssemblyName); HbmSerializer.Default.Serialize(stream, assembly); stream.Position = 0; base.Configuration.AddInputStream(stream); } } /// <summary> /// 重写父类AfterPropertiesSet /// </summary> public override void AfterPropertiesSet() { base.AfterPropertiesSet(); AddInputStream(); } } }
在Spring.Net 的配置文件中 使用自定义的 LocalSessionFactoryObject 类
<object id="NHibernateSessionFactory" type="Dao.RepositoryDao.MyLocalSessionFactoryObject, Dao.RepositoryDao"> <property name="DbProvider" ref="DbProvider"/> <!--自定义LocalSessionFactoryObject中的属性 指实体类所在程序集的名称--> <property name="ModelAssemblyNames"> <list> <value>Domain.Model</value> </list> </property> <property name="HibernateProperties"> <dictionary> <entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/> <entry key="dialect" value="NHibernate.Dialect.MsSql2000Dialect"/> <entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/> <entry key="use_outer_join" value="true"/> <entry key="show_sql" value="false"/> <entry key="adonet.batch_size" value="10"/> <entry key="command_timeout" value="60"/> <entry key="query.substitutions" value="true 1, false 0, yes 'Y', no 'N"/> <entry key="proxyfactory.factory_class" value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"/> </dictionary> </property> <property name="ExposeTransactionAwareSessionFactory" value="true" /> </object>