.net-coreipcmicroservicesazureservicebusmasstransit

MassTransit. Consume equal objects defined in different namespaces


First of all, excuse my English, it's very bad. I am using MassTransit with Azure Service Bus for asynchronous communication between microservices. By their own definition, and to avoid generating dependencies between them, messages sent between different microservices are defined in each of them, that is, they are part of different namespaces. The automatic management of MassTransit causes queues and topics to be managed by the object type, which prevents the microservices that consume a message from receiving the messages sent by the microservice publisher. The same thing happens with two classes with the same properties in the same namespace but with a different class name.

Is there any way to solve this? The options that have occurred to me are:

I leave an example that I hope can help you in understanding the problem.

//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();
        }
    }
}

Thank you very much.

regards

Borja


Solution

  • The message type, and the resulting name, are a key concept within MassTransit. If you want to avoid sharing assemblies between projects, that is fine, but you will need to match the entire interface (or class, in your case) name, including namespace, or it will not route properly.

    Yes, you can override the entity name formatter to change how topics are named but it won't change the message type requirement for deserialization of the message (which happens, by type).

    So the recommendation here is to use the same namespace for the contracts, even if they're in separate projects.