Skip to content

Instantly share code, notes, and snippets.

@ianfnelson
Created September 18, 2014 12:38
Show Gist options
  • Save ianfnelson/2f0f9300f5157c320dbd to your computer and use it in GitHub Desktop.
Save ianfnelson/2f0f9300f5157c320dbd to your computer and use it in GitHub Desktop.
Snippets for 2010 blog post "WCF - NHibernate Unit Of Work Endpoint Behavior"
using System;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
/// <summary>
/// Being a custom EndpointBehavior added to the WCF services such that each operation begins a
/// new unit of work when invoked, and closes the same unit of work after invocation.
/// </summary>
/// <remarks>
/// In practice, we are using this simply to manage NHibernate sessions - opening a new Session at
/// the start of each operation, and closing it as the operation completes.
/// </remarks>
public class UnitOfWorkEndpointBehavior : IEndpointBehavior
{
/// <summary>
/// Local instance of unit of work implementation.
/// </summary>
/// <remarks>
/// Interface is ORM-agnostic, it need not be NHibernate.
/// </remarks>
private IUnitOfWork unitOfWork;
/// <summary>
/// Initializes a new instance of the UnitOfWorkEndpointBehavior class.
/// </summary>
/// <param name="unitOfWork">Unit of Work</param>
public UnitOfWorkEndpointBehavior(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
// Add a new Unit of Work call context initializer to every operation.
foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
{
operation.CallContextInitializers.Add(new UnitOfWorkCallContextInitializer(this.unitOfWork));
}
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
/// <summary>
/// Custom call context initializer added to all WCF operations such that each operation begins
/// a new unit of work when invoked, and closes the same unit of work after invocation.
/// </summary>
/// <remarks>
/// In practice, we are using this simply to manage NHibernate sessions - opening a new Session at
/// the start of each operation, and closing it as the operation completes.
/// </remarks>
public class UnitOfWorkCallContextInitializer : ICallContextInitializer
{
/// <summary>
/// Local instance of unit of work implementation.
/// </summary>
/// <remarks>
/// Interface is ORM-agnostic, it need not be NHibernate.
/// </remarks>
private IUnitOfWork unitOfWork;
/// <summary>
/// Initializes a new instance of the UnitOfWorkCallContextInitializer class.
/// </summary>
/// <param name="unitOfWork">Unit of Work</param>
public UnitOfWorkCallContextInitializer(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
/// <summary>
/// Method fired after the operation is invoked.
/// </summary>
/// <param name="correlationState"></param>
public void AfterInvoke(object correlationState)
{
// End the unit of work (closes the NH session).
this.unitOfWork.End();
}
/// <summary>
/// Method fired before the operation is invoked.
/// </summary>
/// <param name="instanceContext"></param>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
{
// Begin a new unit of work (opens the NH session).
return this.unitOfWork.Start();
}
}
container.Register(
Component.For<UnitOfWorkEndpointBehavior>()
.Attribute("scope").Eq(WcfExtensionScope.Services));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment