NHibernate会话在每次wcf服务方法调用时都会被处理掉

时间:2010-07-07 08:50:59

标签: wcf nhibernate s#arp-architecture

我在Sharp Architecture中使用Wcf。我使用WcfSessionStorage等在northwind示例之后配置了我的项目。我在wcf服务中有一个方法,它使用Repository<> .GetAll()获取业务对象列表。我正在使用WcfTestClient测试服务方法。当第一次调用该方法时,一切正常。但是在随后的调用中,我在Repository<> .GetAll()方法上得到以下异常

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

似乎每次调用后NHibernate会话都会被释放。我通过使用以下属性

来装饰我的服务解决了这个问题
[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}

然而,这意味着,将在每次调用时创建一个服务实例,这反过来将创建一个新的nhibernate会话等。在我的场景中,不需要为每个调用创建一个新的服务实例,我认为它很昂贵过程而不是正确的解决方案。我想知道我的场景中的最佳实践是什么,以及如何通过为每次调用创建新的服务实例来使这件事工作。

由于 纳比尔

2 个答案:

答案 0 :(得分:2)

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

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

如果您的服务是单件服务: 在第一次运行时,服务被创建,该服务使用ISession,它应该是容器范围的,并且它是在第一次运行时。 下一个服务请求(现在已创建服务)仍然引用了创建的ISession(在前一个请求时关闭),所以现在它已关闭。

我不建议使用你打开/关闭的同一个ISession(它不是在NHibernate文档中推荐的),只是使用容器作用域(我这样做,我没有任何性能问题),或者你应该在服务的每个方法中手动创建ISession,如:

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

但这根本不好......

答案 1 :(得分:1)

请查看我对自己类似问题的回答:WCF/S#arpArch: underlying ISession is closed after the first call within a request

@dmonlord是正确的,在这种情况下,在同一请求中创建额外的会话实例非常便宜。