如何在两个微服务之间实现Rebus订阅/发布,DTO副本位于不同的程序集中?

时间:2018-02-26 13:59:20

标签: rebus

我正在使用Rebus来处理以下一般情况,对于WCF或WebAPI来说是自然的。有两个微服务,在它们的程序集中具有相同的DTO集合,用于交换集成事件。 DTO类是类似的,但它们驻留在具有不同.Net Core和.Net Framework框架的不同程序集中。要在单独的共享程序集中创建DTO,我不愿意。如何根据位于不同程序集中的两个DTO副本实现订阅/发布以交换这两个微服务之间的集成事件?

第一个微服务的例子:

public class Message
{
    public int MessageNumber { get; set; }
}

class Program
{
    static void Main()
    {
        using (var adapter = new BuiltinHandlerActivator())
        {
            Configure.With(adapter)
                .Logging(l => l.ColoredConsole(LogLevel.Warn))
                .Transport(t => t.UseRabbitMqAsOneWayClient("amqp://myRebbitMQ"))
                .Start();

            var keepRunning = true;
            while (keepRunning)
            {
                var key = char.ToLower(Console.ReadKey(true).KeyChar);
                switch (key)
                {
                    case 'f':
                        Console.WriteLine("Publishing {0} messages", 1000);
                        var jobs = Enumerable.Range(0, 1000)
                            .Select(i => new Message { MessageNumber = i })
                            .Select(m => adapter.Bus.Publish(m))
                            .ToArray();
                        Task.WaitAll(jobs);
                        break;
                    case 'q':
                        Console.WriteLine("Quitting");
                        keepRunning = false;
                        break;
                }
            }
        }
    }
}

第二个微服务的例子:

public class Message
{
    public int MessageNumber { get; set; }
}

public class MessageHandler : IHandleMessages<Message>
{
    public async Task Handle(Message message)
    {
        Console.WriteLine("Processing message {0}", message.MessageNumber);

        await Task.Delay(200);
    }
}

class Program
{
    private static IContainer _container;
    static void Main()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<MessageHandler>().As(typeof(IHandleMessages<>).MakeGenericType(typeof(Message)));
        builder.RegisterRebus((configurer, context) => configurer
            .Logging(l => l.ColoredConsole(LogLevel.Warn))
            .Transport(t => t.UseRabbitMq("amqp://myRebbitMQ", "consumer2"))
            //.Serialization(s => s.UseNewtonsoftJson(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects })) ???
            .Options(o => o.SetMaxParallelism(5))
        );
        using (_container = builder.Build())
        {
            var eventBus = _container.Resolve<IBus>();
            eventBus.Subscribe<Message>().Wait();
            Console.WriteLine("Consumer listening - press ENTER to quit");
            Console.ReadLine();
        }
    }
}

1 个答案:

答案 0 :(得分:2)

虽然Rebus具有基于类型的pub / sub的突出API,但底层实现适用于普通的基于字符串的主题。

这意味着例如

await bus.Subscribe<YourMessage>();

await bus.Publish(new YourMessage());

简单地转换为主题"YourMessages.YourMessage, YourMessages"的订阅和发布操作(这里假装YourMessage位于YourMessages程序集中。

您可以使用主题API访问基于主题的原始API,您可以在此处获取:

var topics = bus.Advanced.Topics;

然后你可以

await topics.Subscribe("to anything");

await topics.Publish("to anything", new YourMessage());

因此,为了解决您的问题,我建议您利用此功能并确定每种事件类型的常见主题。