11

所以我真的很喜欢使用NHibernate,但总是使用 Spring.Net。

我最近遇到了 Jeremy Miller 的 StructureMap,我真的比 Spring.Net 更喜欢它。在他的 StructureMap 网站上,他承诺了一个如何一起使用 NHibernate 和 StructureMap 的示例。不幸的是,他没有时间去做(或者我找不到)。

那么有人有关于如何使用 StructureMap 处理 NHibernate 会话的示例吗?

4

3 回答 3

23

所以,我很抱歉我们之前没有完成带有 StructureMap 的 NHibernate 示例。最终,我想在 StructureMap 文档中发布它,但我首先需要一些反馈。你可以在我的博客上看到完整的例子:

http://trason.net/journal/2009/10/7/bootstrapping-nhibernate-with-structuremap.html

话虽如此,我可以在这里打出亮点。有一个 NHibernateRegistry 提供了四样东西:一个 NHibernate.Configuration(作为一个单例),一个 ISessionFactory(作为一个单例),一个 ISession(范围混合(HttpContext 如果可用,回退到线程本地存储))和一个非常简单的 IUnitOfWork。此外,还有一个 HttpModule 来管理每个 Web 请求的 UnitOfWork。

这是 NHibernateRegistry 的代码:

using NHibernate;
using NHibernate.ByteCode.Castle;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernateBootstrap.Core.Domain;
using StructureMap.Attributes;
using StructureMap.Configuration.DSL;
using Environment=NHibernate.Cfg.Environment;

namespace NHibernateBootstrap.Core.Persistence
{
    public class NHibernateRegistry : Registry
    {
        public NHibernateRegistry()
        {
            var cfg = new Configuration()
                .SetProperty(Environment.ReleaseConnections, "on_close")
                .SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionString, "data source=bootstrap.sqlite;Version=3")
                .SetProperty(Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
                .AddAssembly(typeof(Blog).Assembly);

            var sessionFactory = cfg.BuildSessionFactory();

            ForRequestedType<Configuration>().AsSingletons().TheDefault.IsThis(cfg);

            ForRequestedType<ISessionFactory>().AsSingletons()
                .TheDefault.IsThis(sessionFactory);

            ForRequestedType<ISession>().CacheBy(InstanceScope.Hybrid)
                .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());

            ForRequestedType<IUnitOfWork>().CacheBy(InstanceScope.Hybrid)
                .TheDefaultIsConcreteType<UnitOfWork>();

                ForRequestedType<IDatabaseBuilder>().TheDefaultIsConcreteType<DatabaseBuilder>();
        }
    }
}

这是工作单元的代码:

using System;
using NHibernate;

namespace NHibernateBootstrap.Core.Persistence
{
    public interface IUnitOfWork : IDisposable
    {
        ISession CurrentSession { get; }
        void Commit();  
    }
}

using NHibernate;

namespace NHibernateBootstrap.Core.Persistence
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly ISessionFactory _sessionFactory;
        private readonly ITransaction _transaction;

        public UnitOfWork(ISessionFactory sessionFactory)
        {
            _sessionFactory = sessionFactory;
            CurrentSession = _sessionFactory.OpenSession();
            _transaction = CurrentSession.BeginTransaction();
        }

        public ISession CurrentSession { get; private set;}

        public void Dispose()
        {
            CurrentSession.Close();
            CurrentSession = null;
        }

        public void Commit()
        {
            _transaction.Commit();
        }
    }
}

这是用于 Web 应用程序的 NHibernateModule:

using System;
using System.Web;
using NHibernateBootstrap.Core.Persistence;
using StructureMap;

namespace NHibernateBootstrap.Web
{
    public class NHibernateModule : IHttpModule
    {
        private IUnitOfWork _unitOfWork;

        public void Init(HttpApplication context)
        {
            context.BeginRequest += ContextBeginRequest;
            context.EndRequest += ContextEndRequest;
        }

        private void ContextBeginRequest(object sender, EventArgs e)
        {
            _unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();

        }

        private void ContextEndRequest(object sender, EventArgs e)
        {
            Dispose();
        }

        public void Dispose()
        {
            _unitOfWork.Dispose();
        }
    }
}
于 2009-10-10T03:39:27.687 回答
0

这有帮助吗: http: //devlicio.us/blogs/billy_mccafferty/archive/2007/02/05/inject-di-container-into-domain-objects-with-nhibernate.aspx

于 2009-07-24T09:54:50.770 回答
0
  • 在此处编辑:我在发布 wbinford 的答案之前发布了此评论。我仍然认为使用 NCommon 是好的,但他上面的答案更简洁一些,不需要使用其他第三方工具。

我真的没有得到我想要的答案,但我找到了一个很好的框架,叫做NCommon。它使用 NHibernate、LinqToSql 或实体框架实现了工作单元模式以及存储库模式。它还处理 NHibernate ISession 以及 NHibernate 的配置。我将该工具与 StructureMap 和 NHibernate 一起使用。我确实必须获得 StructureMap 的服务适配器,但是一旦设置它就可以很好地工作。

于 2009-08-24T19:50:09.007 回答