4

I have an IIS hosted WCF service with single-call behavior. I use Fluent NH for data access and faced the following issue. I cannot close/dispose NH session inside of method body because when serialization comes to the game it cannot access lazy loaded fields. I tried to use approach described in answer for this question NHibernate session management in WCF application but it turns their session disposal also happens before serialization starts.

Do you know if I can execute any code in instance context after serialization is finished?

Thanks

Community
  • 1
  • 1
Alex Krupnov
  • 460
  • 3
  • 8

2 Answers2

2

So I found a compromised solution. I'm still using IDispatchMessageInspector implementation from the link above, but I perform the extension detach in a different way.

Here is a snippet from original implementation

        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);
            }
        }

I leave BeforeSendReply message empty (as it happens prior to Serialization), but instead inside of AfterReceiveRequest I suscribe to instanceContext.Closing and detach extension in event handler

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;
        }
Alex Krupnov
  • 460
  • 3
  • 8
  • You sir, are awesome. I have been struggling with the same question the whole day before I found this answer. +1! – dvdvorle Feb 09 '12 at 16:53
0

I am also interested in proper solution.

Because NHibernate types cause issues with WCF serialization (even for loaded objects), I recursively go through the object graph and replace all proxies with real objects and basic .NET collections with the help of reflection. This way all objects returned by WCF methods are plain DTOs with no references to NHibernate.

I do this explicitly within the WCF method:

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
}
Arunas
  • 918
  • 1
  • 8
  • 20