【问题标题】:ASP.NET MVC and NHibernate couplingASP.NET MVC 和 NHibernate 耦合
【发布时间】:2010-04-19 12:12:25
【问题描述】:

我刚刚开始学习 NHibernate。

在过去的几个月里,我一直在使用 IoC / DI(结构图)和存储库模式,它使我的应用程序更加松散耦合并且更易于测试。

在将我的持久层切换到 NHibernate 时,我决定坚持使用我的存储库。目前我正在为每个方法调用创建一个新会话,但这当然意味着我无法从延迟加载中受益。

因此,我希望实现每个请求的会话,但这样做会使我的 Web 项目依赖于 NHibernate(也许这不是一件坏事?)。我计划将 ISession 注入到我的存储库中,并在 beginrequest/endrequest 事件上创建和处理会话(请参阅http://ayende.com/Blog/archive/2009/08/05/do-you-need-a-framework.aspx

这是一个好方法吗?如果在我的网络项目中没有对 NHibernate 的引用,我大概无法使用 session-per-request?

让网络项目依赖于 NHibernate 会提示我下一个(几个)问题 - 为什么还要麻烦存储库?由于我的 Web 应用程序正在调用与存储库通信的服务,为什么不放弃存储库并在服务中添加我的 NHibernate 持久性代码?最后,真的有必要分成这么多项目吗?一个网络项目和一个基础设施项目就足够了吗?

我意识到我已经偏离了最初的问题,但似乎每个人似乎对这些话题都有自己的看法。有些人将存储库模式与 NHibernate 一起使用,有些人则没有。有些人将他们的映射文件与相关类粘贴在一起,其他人为此有一个单独的项目。

非常感谢, 本

【问题讨论】:

  • 我刚开始使用 MVC...老实说,我认为延迟加载在视图中没有用。我只是确保热切地加载适当的字段。如果会话的范围保持在操作方法内,IMO 事情就会简单得多。
  • 它在视图中可能没有用,但在用于构建视图模型的服务中肯定有用,并且它在存储库层节省了一些复杂性。一个示例是具有许多订单行的订单。在显示列表或订单的页面上,我不想急切地加载每个 OrderLine。但是,当我深入了解订单时,我想要 OrderLines。使用延迟加载可以让我拥有一个简单的订单存储库,这意味着我不需要额外的存储库方法来加载订单行。
  • 只是关于会话范围的注释 - 包含由不同操作(例如使用 RenderAction)呈现的多个部分视图的页面怎么样。当然,保存同一个会话(每个页面请求)比每个操作都有一个会话更好吗?
  • 是的,我同意你的看法……延迟加载非常好,我一直都在使用它(只是不在视图代码中)。我还没有使用 RenderAction,所以也许我最终需要跨操作重用会话。

标签: asp.net-mvc nhibernate


【解决方案1】:

我不会让业务逻辑依赖于 NHibernate。我写了一个(或多或少简单的)类来将会话创建到上下文中:

using (TransactionService.CreateTransaction())
{
  // use repository here

  // rollback on exception, only commit when reach this last line:
  TransactionService.Commit();
}

你只需要一个 IDisposable,你不需要知道会话。

存储库获取一个 API 来访问会话。例如:

// example repository implementation
public Entity Get(Guid id)
{
  return SessionProvider.Session.Get<Entity>(id);
}

为了实现这一点,我将会话放入ThreadStatic 变量中,该变量在CreateTransaction 中初始化并由SessionProvider.Session 返回。

【讨论】:

  • @Stefan,你能解释一下这是如何与每个请求的会话一起工作的吗?您如何/在哪里创建和处置会话?
  • 我在TransactionService.CreateTransaction 中创建会话。在那里我返回一个实现IDisposable 的小类并在Dispose 中调用TransactionService(我实际上发送了一个由TransactionService 在创建此对象时注册的事件。)会话关闭。当您的请求进来时,您使用TransactionService.CreateTransaction 打开事务。然后它就在那里。
  • 愿意分享您的 TransactionService 的代码吗?没有冒犯,但上面的代码并没有真正帮助我。
  • 它由一些类组成,并与我们的基础设施耦合。因此,即使我可以,它也不会对您有太大帮助。关键是代表上下文的 ThreadStatic 变量。其余的实际上只是一个围绕它构建的 API。
【解决方案2】:

看看S#arp Architecture。它回答了您需要的一切,包括如何分离数据层 (NHibernate)、Web 层和业务逻辑。

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多