IBusControl Publish 在包装到另一个 class 时什么都不做

IBusControl Publish does nothing while wrapped into another class

我正在为 MassTransit 苦苦挣扎,这是另一个我未能解决的棘手问题。 当我直接调用 Publish 方法时,一切正常,消息被发送到 RMQ。但是当我用自己的方法包装这个方法并在包装器 class' 构造函数中注入总线时,它不起作用。消息根本无法到达总线。

using (var uow = new Wrapper(ctx, bus))
{
    var itemMsg = new ItemChangedMessage() { Value = item.Value };

    uow.Publish(itemMsg); //Does not work

    bus.Publish(itemMsg); //Works fine
}

这是一个包装器 class' 方法。没什么特别的。

public void Publish(IMessage message)
{
    bus.Publish(message);
    ...
}

我完全不知道这里会出现什么样的问题。尝试了 async\await 的不同组合,但没有任何帮助。

我想 Publish 是通用的,并且您的方法中使用了不同的重载。将您的方法签名更改为:

public void Publish<T>(T message) where T : IMessage

我认为您的包装器会在调用完成之前被处理掉,因为您没有等待发布。您 必须 执行 async/await 或者您可以在包装器中使用 TaskUtil.Await(() => bus.Publish(message));

这应该有效:

using (var uow = new Wrapper(ctx, bus))
{
    var itemMsg = new ItemChangedMessage() { Value = item.Value };

    await uow.Publish(itemMsg);
}

...

public async Task Publish(object message)
{
    await bus.Publish(message);
    ...
}

但主要问题确实是另外一回事。正如另一个答案中正确指出的那样,您使用的是类型化重载 Publish<T>(T message),但您的 TIMessage,因此 MassTransit 会将其发布到 IMessage 交换,因为您很可能订阅 ItemChangedMessage,您的消费者永远不会收到它。

查看调试日志时可以很容易地看到这一点:

[15:51:06 DBG] Exchange: BusWrapper:IMessage (durable)

[15:51:06 DBG] SEND rabbitmq://localhost/BusWrapper:IMessage 1b340000-da2d-1866-1043-08d4de648414 BusWrapper.IMessage

你不需要用任何接口来标记你的消息,它只会产生不必要的交换和依赖,你想把你的消息接口作为一个库来共享吗?根据此答案中的更新代码,您可以使用 public async Task Publish(object message) 就好了。

或者,您可以使用 Publish(object message) 重载,它会为您找到类型并正确发布。在这种情况下,您需要在包装器中包含:

public async Task Publish(IMessage message)
{
    await bus.Publish((object) message);
    ...
}