10

I created a microservice application that microservices using MassTransit and RabbitMQ for communication.
Each microservice developed using clean architecture, so we have MediatR inside each microservice.
Is it possible to use MassTransit for inside communication as well? so I can use the same signature for all services and when I want to expose a service to be used inter-microservice, it will be doable with ease. So MediatR used for intra-communication and RabbitMQ used for inter-communication, and whole universe is on MassTransit system.
[Update] My question is how we can configure consumers so some can be used for inside communication (via MediatR) and some can be used for external communication (via RabbitMQ) and easily change them from inside to outside.
[Update2] for example here is my MassTransit registration:

services.AddMassTransit(x =>
        {
            x.AddConsumers(Assembly.GetExecutingAssembly());

            x.AddBus(provider =>
                Bus.Factory.CreateUsingRabbitMq(cfg =>
                {
                    cfg.Host(new Uri(config.RabbitMQ.Address), h =>
                    {
                        h.Username(config.RabbitMQ.Username);
                        h.Password(config.RabbitMQ.Password);
                    });

                    cfg.ReceiveEndpoint("my-queue", ep => { ep.ConfigureConsumers(provider); });
                }));


            x.AddMediator((provider, cfg) => { cfg.ConfigureConsumers(provider); });
        });

How can I differ in internal communication and external communication? in other words, how can I register some consumers to MediatR and some to RabbitMQ?

Mahdi
  • 725
  • 2
  • 7
  • 24
  • Based upon your update, you would need to use the MassTransit mediator to have a single interface for consumers that you could move to either mediator or RabbitMQ endpoints. – Chris Patterson May 31 '20 at 12:22

2 Answers2

10

They can be used together, and MassTransit has its own Mediator implementation as well so you can write your handlers once and use them either via the mediator or via a durable transport such as RabbitMQ.

There are videos available that take you through the capabilities, starting with mediator and moving to RabbitMQ.

Chris Patterson
  • 28,659
  • 3
  • 47
  • 59
  • 1
    Thanks for your comment. Actually I know it's possible to use both. I want to know how we can configure consumers that some used for inside communication (via MediatR) and some used for external communication (via RabbitMQ) – Mahdi May 30 '20 at 04:48
  • 1
    can we use main mediatR library with mass transit ? @Chris – mohammadmahdi Talachi Jan 18 '21 at 12:56
  • 1
    Sure? I haven't used MediatR, so I have no idea how it works but I imagine the two can be used in the same project. They are not, however, _integrated_ to work together. – Chris Patterson Jan 18 '21 at 14:02
6

I found that I should create a separate bus for each. then external services inherit from an interface like IExternalConsumer, so I can separate them form internal ones and add them to related bus: UPDATED for version 7

        // find consumers
        var types = AssemblyTypeCache.FindTypes(new[]{Assembly.GetExecutingAssembly()},TypeMetadataCache.IsConsumerOrDefinition).GetAwaiter().GetResult();
        var consumers = types.FindTypes(TypeClassification.Concrete | TypeClassification.Closed).ToArray();
        var internals = new List<Type>();
        var externals = new List<Type>();
        foreach (Type type in consumers)
        {
            if (type.HasInterface<IExternalConsumer>())
                externals.Add(type);
            else
                internals.Add(type);
        }

        services.AddMediator(x =>
        {
            x.AddConsumers(internals.ToArray());
            x.ConfigureMediator((provider, cfg) => cfg.UseFluentValidation());
        });
        services.AddMassTransit<IExternalBus>(x =>
        {
            x.AddConsumers(externals.ToArray());
            x.AddBus(provider =>
                Bus.Factory.CreateUsingRabbitMq(cfg =>
                {
                    cfg.Host(new Uri(config.RabbitMQ.Address), h =>
                    {
                        h.Username(config.RabbitMQ.Username);
                        h.Password(config.RabbitMQ.Password);
                    });

                    cfg.ReceiveEndpoint(apiProviderName, ep => { ep.ConfigureConsumers(provider); });

                }));
        });

        services.AddMassTransitHostedService();
Mahdi
  • 725
  • 2
  • 7
  • 24
  • Just to update, with v7, the .AddMediator() and .AddMassTransit() can be configured in the same container without using a separate bus. – Chris Patterson Jul 23 '20 at 20:17
  • 1
    I've been trying with MassTransit.AspNetCore 7.0.3 but cannot do .AddMediator(). services.AddMassTransit(cfg => { cfg.AddConsumer(); cfg.AddMediator(); // <- this line doesn't work. no definition found. }); – Ceemah Four Aug 15 '20 at 10:04
  • 1
    With that approach should I use MassTransit interfaces in my controllers or MediatR ones? Can you share any sample solution? – SzymonB Dec 17 '20 at 09:16
  • Currently migrating to V8 and had a hard Time with TypeMetadataCache.IsConsumerOrDefinition. For everyone running into the same problem, it is now RegistrationMetadata.IsConsumerOrDefinition – Patrick Aug 12 '22 at 08:02