2010-07-07 55 views
2

我在夏普体系结构中使用Wcf。我使用WcfSessionStorage等配置了Northwind示例后的项目。我在wcf服务中有一个方法,它使用Repository <> .GetAll()获取业务对象列表。我正在使用WcfTestClient测试服务方法。当第一次调用该方法时,一切正常。然而在随后的电话,我得到下面的异常的存储库<> .GetAll()方法NHibernate会话在每次wcf服务方法调用时都被处理掉

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

好像NHibernate会话被每次通话后配置。我已经用下面的属性

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class WcfService : IWcfService 
{ 
} 

然而,这意味着,该服务的一个实例会在每次调用创建这反过来将创建一个新的NHibernate会话等。在我的场景装饰我的服务解决这个问题了没有必要为每个呼叫创建一个新的服务实例,我认为它是一个昂贵的过程,而不是正确的解决方案。我想知道我的方案中的最佳做法是什么,以及如何通过每次调用创建新的服务工作站来实现此目标。

感谢 纳比尔

回答

2

最简单的方法是每次创建新实例,它不是一个昂贵的过程,因为在.NET中创建一个新的对象是像0.00000000000000001秒(我读了关于Ayande的博客或某处)。

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

如果您的服务是单件服务: 在第一次运行时创建服务,此服务使用ISession,它应该是容器作用域,并且处于第一次运行状态。 服务的下一个请求(服务现在已创建)仍然对创建的ISession(在前一个结束请求中已关闭)有参考,因此现在它已关闭。

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

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

但是,这是不是很好在所有...

相关问题