Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NHibernate会话在每次wcf服务方法调用时被释放_Wcf_Nhibernate_S#arp Architecture - Fatal编程技术网

NHibernate会话在每次wcf服务方法调用时被释放

NHibernate会话在每次wcf服务方法调用时被释放,wcf,nhibernate,s#arp-architecture,Wcf,Nhibernate,S#arp Architecture,我正在夏普架构中使用Wcf。我已经使用WcfSessionStorage等配置了northwind示例之后的项目。我在wcf服务中有一个方法,该方法使用Repository.GetAll()获取业务对象列表。我正在使用WcfTestClient测试服务方法。第一次调用该方法时,一切正常。但是,在随后的调用中,我在Repository.GetAll()方法上遇到以下异常 似乎NHibernate会话在每次调用后都会被释放。通过使用以下属性来装饰我的服务,我解决了这个问题 [ServiceBehav

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

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

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

谢谢
Nabeel

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

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

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

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

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

但这一点都不好…

请看我对自己类似问题的回答:

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

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