【发布时间】:2012-06-06 18:49:02
【问题描述】:
我有 NServiceBus (3.2.2) 设置,使用 Castle Windsor 作为它的构建器,我也在使用 NHibernate。我遇到的问题是,在我的处理程序中,如果我有多个需要 NHibernate 会话的存储库,它们最终会得到 不同的 会话!
NServiceBus 文档声明容器内的任何transient 实例都将被视为singleton 实例。我的 NHibernate 会话也包含在一个工作抽象单元中。
下面是使用 NHibernate 设置 NServiceBus 的代码:
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();
UnitOfWorkInstaller 有点像:
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())));
因此,当需要 NHibernate 会话时,它会使用 UnitOfWorkFactory 创建。我尝试在 NHibernate 配置中将 'current_session_context_class' 属性设置为 'thread_static' 但它不起作用。
为什么我的 NServiceBus 处理程序中有不同的工作单元?
【问题讨论】:
-
我不相信这一点:NServiceBus 文档指出容器内的任何瞬态实例都将被视为单例实例。
-
@mynkow "NServiceBus 为收到的每个传输消息创建一个子容器,请记住传输消息可以包含多个“用户定义的消息”。这意味着在该消息处理期间创建的所有瞬态实例在子容器中的作用域为单例。这使您可以轻松地在存储库之间共享 NHibernate 会话,而无需使用线程静态缓存。你可以找到相关文档here
-
它似乎已经改变了,因为查看源代码你可以看到新的 NServiceBus 生命周期枚举
InstancePerUnitOfWork意味着“在工作单元的持续时间内,实例将是单例的。在实践中这意味着处理单个传输消息”,并且该值映射到LifestyleType.ScopedWindsor Castle 枚举...所以我会尝试 -
另外,当你使用 'current_session_context_class' 时,你应该得到像 sessionFactory.GetCurrentSession() 这样的会话
-
@mynkow 是的,我正在考虑重构我的这部分代码,这样我就可以使用 NHibernate 的会话上下文功能,而不是使用工厂方法创建 ISession 并让容器管理其生命周期/跨度>
标签: nhibernate isession nservicebus3