有没有办法让消息作为一个类发送给每个接口使用,这个类实现了?

时间:2021-02-10 15:49:18

标签: masstransit

假设我有一个类 C,它实现了接口 I1 和 I2

namespace Contract
{
    public class C :I1,I2
    {
    }
    public interface I1 { }
    public interface I2 { }
}

所以,我会在我的制作人的某个地方发布 C:

...
var message c = new C();
await _busControl.Publish(c);
...

在我的 I1 消费者中,我希望拥有:

        cfg.Host("localhost", "/");

        cfg.ConfigureMessageTopology();

        cfg.ReceiveEndpoint("subs", endpoint =>
        {
            endpoint.Durable = false;
            endpoint.Handler<I1>(context =>
            {
               ...
            });
          };

在我的 I2 消费者中,我希望拥有:

         cfg.Host("localhost", "/");

        cfg.ConfigureMessageTopology();

        cfg.ReceiveEndpoint("subs", endpoint =>
        {
            endpoint.Durable = false;
            endpoint.Handler<I2>(context =>
            {
               ...
            });
          };

是否可以使用现有代码配置这样的路由? 如果没有,这是一种正确的方法吗? 如果我想实现这一点,建议采用什么方法?

2 个答案:

答案 0 :(得分:2)

默认情况下,使用 RabbitMQ 和 Azure 服务总线即可工作。

它不适用于 Amazon SQS 或 ActiveMQ。

MassTransit 将其称为多态消息路由,您可以在 the documentation 中看到拓扑是如何配置的。

要清理您的示例,这就是您所需要的:

namespace Contract
{
    public class C :
        I1,I2
    {
    }
    public interface I1 { }
    public interface I2 { }
}

然后发布:

var message c = new C();
await _busControl.Publish(c);

第一消费者:

class OneConsumer :
    IConsumer<I1>
{
    public async Task Consume(ConsumeContext<I1> context)
    {
    ...
    }
}

cfg.ReceiveEndpoint("one", endpoint =>
{
    endpoint.Durable = false;
    endpoint.Consumer<OneConsumer>();
};

第二消费者:

class TwoConsumer :
    IConsumer<I2>
{
    public async Task Consume(ConsumeContext<I2> context)
    {
    ...
    }
}

cfg.ReceiveEndpoint("two", endpoint =>
{
    endpoint.Consumer<TwoConsumer>();
};

答案 1 :(得分:1)

它开箱即用。您无需执行任何操作即可使其正常工作。

唯一可能遇到麻烦的情况是,如果您使用返回接口的函数创建消息。由于 MassTransit 将使用通用重载 Publish<T>,因此它只会使用接口。在这种情况下,你可以说:

object message = MyMessageFactory();
await bus.Publish(message);

MassTransit 会找出类型。

但是,在您的场景中,它再次起作用。