如何在构建依赖项时查看消息?

How to peek at message while dependencies are being built?

我将多租户构建到一组服务的工作单元中。我想让租赁问题远离 day-to-day 业务领域的工作,并且我不想触及系统中的每个现有消费者(我正在将多租户改造到一个没有任何租户概念的系统上).

系统中的大多数消息都将由租户关联。但是,会有一些基础设施消息不会,特别是为了自动创建租户。我需要一种方法来确定是使用 tenant-contexted 工作单元,还是使用与租户无关的基础设施工作单元,因为我与数据库交互的方式因我是否有租户上下文而异。工作单元是在旋转消费者的依赖关系的过程中构建的。

因此,我需要一种在使用消息之前查看消息或其元数据的方法,具体来说,我需要能够在依赖项构建期间查看它。我打算有一个标签界面来将租户管理消息从正常的业务域消息中标记出来,但是任何形式的识别差异都可以工作。如果我处于由 HTTP 请求产生的工作单元中,我可以查看 WebApi 的 HttpContext.Current 并查看当前请求的 headers 等。如果我是,我该如何做类似的事情在消息传递产生的工作单元中?

我看到有一种方法可以使用 BeforeConsumingMessage() 拦截消息,但我需要一种方法将它与我正在启动的当前工作单元相关联,但我不知道这对我有何作用.我正在尝试做的伪代码:

if MessageContext.Message.GetType() = typeof<ITenantInfrastructureMessage>:
    database = new Database(...)
else:
    tenantId = MessageContext.Headers.TenantId;
    database = new TenantDatabase(..., tenantId)

我在 C#/.NET 中工作,使用带有 RabbitMQ 的 MassTransit 和带有 MassTransit built-in 支持的 Autofac。

您最好的选择是在 IConsumerFactory<T> 扩展点覆盖,并从消息中提取租户(通过消息头或某些消息 属性)并将其注册到容器中子生命周期范围,以便来自实际消费者 class(及其依赖项)的后续解决方案与消息中的租户正确匹配。

在我们的系统中,我们有一个在新创建的 LifetimeScope 中注册的 TenantContext(我们正在使用 Autofac),之后我们从子范围解析消费,使用租户上下文的依赖项获得正确的值,因为它已注册为构建消息范围的子容器的一部分。

它工作得非常好,我们甚至构建了扩展方法,使注册消费者的开发人员可以轻松地指定 "tenant context providers" 从消息类型到正确的租户 ID,用于构建 TenantContext .

您可以对 Courier routing slips(消费者的专业化)中的 activity 工厂做类似的事情。