轨道交通。使用在不同名称空间中定义的相等对象

时间:2018-09-24 10:24:20

标签: .net-core ipc microservices azureservicebus masstransit

首先,请原谅我的英语,这很糟糕。我正在将MassTransit与Azure Service Bus一起用于微服务之间的异步通信。根据它们自己的定义,并且为了避免它们之间产生依赖性,在每个微服务之间定义了在不同微服务之间发送的消息,也就是说,它们是不同名称空间的一部分。 MassTransit的自动管理使队列和主题由对象类型管理,这防止了使用消息的微服务接收到微服务发布者发送的消息。对于具有相同名称空间中相同属性但具有不同类名的两个类,会发生相同的情况。

有什么办法解决这个问题? 我想到的选项是:

  • 从目标地址的端点中删除名称空间,仅使用类名对其进行命名。
  • MassTransit可以基于对象的序列化来管理队列和主题的创建,而不是基于对象的类型(也许通过某种包装对象的类型)来管理队列和主题

我留下一个例子,希望可以帮助您理解问题。

//FIRST PROGRAM - MESSAGE CONSUMER 

namespace Consumer
{
    public class Example
    {
        public string PropOne { get; set; }

        public string PropTwo { get; set; }
    }

    public class ExampleConsumer : 
        IConsumer<Example>
    {
        public List<Example> ConsumedTestObjectList { get; } = new List<Example>();

        //THIS METHOD NEVER CALL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        public Task Consume(ConsumeContext<ExampleConsumer> context)
        {
            ConsumedTestObjectList.Add(context.Message);
            return Task.CompletedTask;
        }
    }

    public class ConsumerProgram
    {
        public static void Main()
        {
            var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
            {
                var host = sbc.Host("connectionString", h => {});

            });

            sbc.ReceiveEndpoint(host, e =>
            {
                e.Consumer<ConsumerProgram.Example>(context =>
                {
                    return Console.Out.WriteLineAsync($"Message Received: {JsonConvert.SerializeObject(context.Message)}");
                });
            });

            bus.Start(); // This is important!

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

            bus.Stop();
        }
    }
}


//SECOND PROGRAM - MESSAGE PUBLISHER 

namespace Publisher
{
    public class Example
    {
        public string PropOne { get; set; }

        public string PropTwo { get; set; }
    }

    public class PublisherProgram
    {
        public static void Main()
        {
            var bus = Bus.Factory.CreateUsingAzureServiceBus(sbc =>
            {
                var host = sbc.Host("connectionString", h => {});

            });

            bus.Start(); // This is important!

            //send new instance of Publisher.Example 
            var example = new Example() { PropOne = "1", PropTwo = "2" };
            bus.Publish(example);

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

            bus.Stop();
        }
    }
}

非常感谢您。

致谢

Borja

1 个答案:

答案 0 :(得分:0)

消息类型和结果名称是MassTransit中的关键概念。如果要避免在项目之间共享程序集,那很好,但是您需要匹配整个接口(或类,在您的情况下)名称(包括名称空间),否则将无法正确路由。

是的,您可以覆盖实体名称格式器以更改主题的命名方式,但不会更改消息反序列化的消息类型要求(按类型发生)。

因此,这里的建议是为合同使用相同的名称空间,即使它们在单独的项目中也是如此。