wcf - NHibernate Session 在每次 wcf 服务方法调用时被释放

标签 wcf nhibernate s#arp-architecture

我正在 Sharp 架构中使用 Wcf。我已经使用 WcfSessionStorage 等按照 Northwind 示例配置了我的项目。我在 wcf 服务中有一个方法,可以使用 Repository<>.GetAll() 获取业务对象列表。我正在使用 WcfTestClient 测试服务方法。当第一次调用该方法时,一切正常。但是,在后续调用中,我在 Repository<>.GetAll() 方法上收到以下异常

[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'

似乎 NHibernate session 在每次调用后都会被释放。我通过使用以下属性装饰我的服务解决了这个问题

[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}
然而,这意味着,每次调用都会创建一个服务实例,进而创建一个新的 nhibernate session 等。在我的场景中,不需要每次调用创建一个新的服务实例,我认为这是一个昂贵的过程过程而不是正确的解决方案。我想知道我的场景中的最佳实践是什么,以及如何通过每次调用创建一个新的服务实例来实现此功能。

谢谢 纳比尔

最佳答案

最简单的方法是每次创建一个新实例,这不是一个昂贵的过程,因为在 .NET 中创建一个新对象大约需要 0.00000000000000001 秒(我在 Ayande 的博客或其他地方读到)。

我在项目中使用 Autofac DI,并且通常将 ISession 作为容器范围(每个请求一个)。然后,每个(直接或间接)使用 ISession 的类都必须是容器范围或更低(工厂范围==每个类使用都会得到一个新实例)。如果使用 ISession 的类具有更高的作用域( session 作用域 == 单例),您将遇到当前遇到的问题。

如果你的服务是单例服务: 第一次运行时会创建服务,该服务使用 ISession,它应该是容器范围的,并且是在第一次运行时。 对服务的下一个请求(服务现已创建)仍然具有对创建的 ISession 的引用(在上一个结束请求时已关闭),因此现在它已关闭。

我不建议使用您将打开/关闭的相同 ISession(NHibernate 文档中不推荐),只需使用容器范围(我这样做并且没有任何性能问题),或者您应该在服务中的每个方法中手动创建 ISession,例如:

using(ISession s = ISessionFactory.OpenSession())
     using(ITransaction t = .....)
....

但这一点都不好......

关于wcf - NHibernate Session 在每次 wcf 服务方法调用时被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3193251/

相关文章:

nhibernate - Fluent NHibernate 将引用映射到不是 ID 列的列

c# - 为 UserControl 填充模型的正确方法是什么?

c# - 在 http//上没有监听端点可以接受 WCF 中的消息

c# - 如何在从 Soap 客户端调用 ASP.Net Web 服务时保留 session

c# - Azure 上的 NHibernate?

nhibernate - 流畅的 NHibernate 映射具有孤立子记录的父/子表

c# - NHibernate - 二级集合缓存不一致

c# - 如何实现历史版本控制?

.net - 在 Silverlight 和 "plain vanilla".Net 之间共享程序集

c# - 在 Windows Azure 中部署 WCF 应用程序