【问题标题】:NServiceBus 3.2 and child containersNServiceBus 3.2 和子容器
【发布时间】: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.Scoped Windsor Castle 枚举...所以我会尝试
  • 另外,当你使用 'current_session_context_class' 时,你应该得到像 sessionFactory.GetCurrentSession() 这样的会话
  • @mynkow 是的,我正在考虑重构我的这部分代码,这样我就可以使用 NHibernate 的会话上下文功能,而不是使用工厂方法创建 ISession 并让容器管理其生命周期/跨度>

标签: nhibernate isession nservicebus3


【解决方案1】:

我通过使用 Castle 的 LifestyleType.Scoped 生活方式来实现它。但是,由于现在显而易见的原因,我的处理程序被一次又一次地调用,直到消息被扔到错误队列中。我之前遇到过这个问题,它与在处理程序中回滚或提交事务有关。在我的工作单元中,我正在重新回滚 Dispose 方法中任何未提交的更改。我唯一要做的就是处理会话并删除 Rollback 调用。

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 2012-03-21
    • 1970-01-01
    相关资源
    最近更新 更多