1

我们正在使用 NServiceBus 为许多租户执行文档处理。

每个租户都有自己的数据库,我们使用 NHibernate 进行数据访问。在 Web 应用程序中,我们使用 IoC 工具 (StructureMap) 来处理会话管理。本质上,我们为每个租户维护一个会话工厂。我们能够从 中识别租户HttpContext

当我们使用 NServiceBus 启动文档处理时,我们可以访问租户标识符。我们需要在整个文档处理过程中都可以使用此租户 ID(我们有 2 个 saga 并触发了许多事件)。

我们需要SessionFactory每个租户创建一个 NHibernate,因此在我们配置 StructureMap 时需要某种方式来获取租户 ID。

我看到一些帖子建议使用消息头来存储租户标识符,但不确定如何:

  1. 在我们第一次提交文档时设置一个消息头(发送一个SubmitDocumentCommand
  2. 在我们配置 StructureMap 时引用 header
  3. 访问我们的 sagas/handlers 中的标题
  4. 确保标头从一条消息流向另一条消息。当我们发送 aSubmitDocumentCommand时,它由DocumentSubmissionSaga. 如果提交成功,我们将发送一个DocumentSubmittedEvent. 我们希望确保租户 ID 在流程中的所有点都可用。

我相信有了这些信息,我可以成功地使用 NHibernate 实现多租户,但是对于这种情况的任何更具体的内容将不胜感激。

4

1 回答 1

4

您可以使用注册自身的消息修改器来传输标头:这是我自己的代码中的一个快速示例。而且您始终可以使用 Bus.CurrentMessageContext.Headers 在任何地方设置/获取标题...

希望这可以帮助 :)

/// <summary>
/// Mutator to set the channel header
/// </summary>
public class FlowChannelMutator : IMutateOutgoingTransportMessages, INeedInitialization
{
    /// <summary>
    /// The bus is needed to get access to the current message context
    /// </summary>
    public IBus Bus { get; set; }

    /// <summary>
    /// Keeps track of the channel
    /// </summary>
    /// <param name="messages"></param>
    /// <param name="transportMessage"></param>
    public void MutateOutgoing(object[] messages, TransportMessage transportMessage)
    {
        if (Bus.CurrentMessageContext != null &&
            Bus.CurrentMessageContext.Headers.ContainsKey("x-messagehandler-channel"))
        {
            if (!transportMessage.Headers.ContainsKey("x-messagehandler-channel"))
            {
                transportMessage.Headers["x-messagehandler-channel"] =
                    Bus.CurrentMessageContext.Headers["x-messagehandler-channel"];
            }
        }
    }

    /// <summary>
    /// Initializes 
    /// </summary>
    public void Init()
    {
        Configure.Instance.Configurer.ConfigureComponent<FlowChannelMutator>(DependencyLifecycle.InstancePerCall);
    }
}
于 2013-08-19T17:02:00.990 回答