I have NServiceBus (3.2.2) setup with Castle Windsor as its builder and I'm also using NHibernate. THe problem I have is that within my handlers if I have multiple repositories that need the NHibernate session, they end up with different sessions!
The NServiceBus document states that any transient instances within the container will be treated as singleton instances. Also my NHibernate session is wrapped in a unit of work abstraction.
Here is the code used to setup NServiceBus with NHibernate:
IWindsorContainer container = new WindsorContainer(new XmlInterpreter());
container.Install(new ContainerInstaller());
container.Install(new UnitOfWorkInstaller(AppDomain.CurrentDomain.BaseDirectory, LifestyleType.Transient));
container.Install(new FactoryInstaller(AppDomain.CurrentDomain.BaseDirectory, LifestyleType.Transient));
container.Install(new RepositoryInstaller(AppDomain.CurrentDomain.BaseDirectory, LifestyleType.Transient));
Configure.With()
.CastleWindsorBuilder(container)
.FileShareDataBus(Properties.Settings.Default.DataBusFileSharePath)
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.JsonSerializer();
The UnitOfWorkInstaller
is someting like:
var fromAssemblyDescriptor = AllTypes.FromAssemblyInDirectory(new AssemblyFilter(_installationPath));
container.Register(fromAssemblyDescriptor
.IncludeNonPublicTypes()
.Pick()
.If(t => t.GetInterfaces().Any(i => i == typeof(IUnitOfWork)) && t.Namespace.StartsWith("Magma"))
.WithService.AllInterfaces()
.Configure(con => con.LifeStyle.Is(_lifeStyleType).UsingFactoryMethod(k => k.Resolve<IUnitOfWorkFactory>().Create())));
So when NHibernate session is need, it gets created with the UnitOfWorkFactory
. I tried putting the 'current_session_context_class' property to 'thread_static' in the NHibernate configuration but it didn't work.
Why am I having different unit of work in my NServiceBus handlers?
I got it working by using Castle's
LifestyleType.Scoped
lifestyle. But then, for now apparent reasons, my handler was called again and again until the message was thrown in the error queue. I had this problem before and it was to do with rollbacking or committing the transaction within the handler. In my unit of work I was reollbacking any uncommitted changes in theDispose
method. The only thing I had to do was only dispose the session and remove theRollback
call.