在WCF序列化返回对象后关闭NHibernate会话

时间:2011-01-31 10:51:59

标签: .net wcf serialization

我有一个具有单一呼叫行为的IIS托管WCF服务。 我使用Fluent NH进行数据访问并遇到以下问题。 我无法关闭/处置方法体内的NH会话,因为当序列化进入游戏时它无法访问延迟加载的字段。 我尝试使用回答中描述的方法来解决这个问题NHibernate session management in WCF application,但是在序列化开始之前它也会发生会话处理。

您知道在序列化完成后我是否可以在实例上下文中执行任何代码?

由于

2 个答案:

答案 0 :(得分:2)

所以我发现了一个妥协的解决方案。 我仍在使用上面链接中的IDispatchMessageInspector实现,但我以不同的方式执行扩展分离。

以下是原始实现的片段

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            var extensions = OperationContext.Current.InstanceContext.Extensions.FindAll<UnitOfWorkContextExtension>();

            foreach (var extension in extensions)
            {
                OperationContext.Current.InstanceContext.Extensions.Remove(extension);
            }
        }

我将BeforeSendReply消息留空(因为它发生在序列化之前),而是在AfterReceiveRequest内部,我接受了instanceContext.Closing并在事件处理程序中分离扩展

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            instanceContext.Extensions.Add(new UnitOfWorkContextExtension(ServiceLocator.IoC.Retrieve<IUnitOfWorkFactory>().Create()));
            instanceContext.Closing += DetachExtension;

            return null;
        }

答案 1 :(得分:0)

我也对正确的解决方案感兴趣。

因为NHibernate类型导致WCF序列化问题(即使对于加载的对象),我递归地遍历对象图并在反射的帮助下用真实对象和基本.NET集合替换所有代理。这样,WCF方法返回的所有对象都是普通的DTO,没有对NHibernate的引用。

我在WCF方法中明确地这样做:

public Document GetDocumentById(int id)
{
    using (var repository = GetRepository()) //Open ISession
    {
        var document = repository.GetDocumentById(id);
        repository.DisconnectObject(document); //Replace proxies
        return document; //Clean object
    } //ISession.Dispose
}