Does MassTransit Request/Response need common .dll's in microservice architecture?

陌路散爱 提交于 2019-12-12 19:07:59

问题


I am going to implement my app in .Net Core, using RabbitMQ and MassTransit in Request/Response pattern.

Here is the code for receiver (it receives the username and password and then sends the username and a provider key to the client):

//BusConfiguration.cs

public static IBusControl ConfigureBus(
        Action<IRabbitMqBusFactoryConfigurator, IRabbitMqHost> registrationAction = null)
    {
        return Bus.Factory.CreateUsingRabbitMq(cfg =>
        {
            var host = cfg.Host(new Uri(RabbitMqConstants.RabbitMqUri), hst =>
            {
                hst.Username(RabbitMqConstants.UserName);
                hst.Password(RabbitMqConstants.Password);
            });

            registrationAction?.Invoke(cfg, host);
        });
    }

public void ConfigureBus()
    {
        bus = BusConfigurator.ConfigureBus((cfg, host) =>
        {
            cfg.ReceiveEndpoint(host, RabbitMqConstants.OAuth2ServiceQueue, e =>
            {
                e.Consumer<CreateUserCommandConsumer>();
            });
        });

        TaskUtil.Await(() => bus.StartAsync());
    }


//CreateUserCommandConsumer.cs
public class CreateUserCommandConsumer : IConsumer<ICreateUserCommand>
{
    public async Task Consume(ConsumeContext<ICreateUserCommand> context)
    {
        await context.RespondAsync<IUserCreatedEvent>(new
        {
            UserName = context.Message.UserName,
            ProviderKey = "q1w2e3d3r"

        });
    }
}

The command and event classes are like below:

 //ICreateUserCommand.cs
namespace WebHost.My.ServiceBus.Messages
{
    public interface ICreateUserCommand
    {
        string UserName { get; set; }
        string Password { get; set; }
    }
}

//IUserCreatedEvent.cs
namespace WebHost.My.ServiceBus.Messages.CreateUser
{
    public interface IUserCreatedEvent
    {
        string UserName { get; set; }
        string ProviderKey { get; set; }
    }
}

And here is the code for my client (sends request for user creation):

        var bus = BusConfigurator.ConfigureBus((cfg, host) =>
        {
            cfg.ReceiveEndpoint(host, "profile.test.service", e =>
            {
            });
        });

        TaskUtil.Await(() => bus.StartAsync());

        try
        {
            IRequestClient<ICreateUserCommand, IUserCreatedEvent> client = CreateRequestClient(bus);

            var userName = "username";
            var password = "password";

            Task.Run(async () =>
            {
                var response = await client.Request(new CreateUserCommand()
                {
                    UserName = userName,
                    Password = password
                });

                Console.WriteLine("User Provider key: {0}", response.ProviderKey);
                Console.WriteLine("User Username: {0}", response.UserName);
            }).Wait();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception!!! OMG!!! {0}", ex);
        }
        finally
        {
            bus.Stop();
        }
    }
    static IRequestClient<ICreateUserCommand, IUserCreatedEvent> CreateRequestClient(IBusControl busControl)
    {
        var serviceAddress = new Uri(RabbitMqConstants.RabbitMqUri + RabbitMqConstants.OAuth2ServiceQueue);
        var client =
            busControl.CreateRequestClient<ICreateUserCommand, IUserCreatedEvent>(serviceAddress, TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60));

        return client;
    }

The point is that the two sides (request side and response side) are different projects with no .ddl in common. In other words, they do not share the IUserCreatedEvent and ICreateUserCommand interfaces. When running the server code (respondent), it creates an exchange named like "WebHost.My.ServiceBus.Messages:ICreateUserCommand" which is a combination of the namespace and interface name. Since I do not have such a namespace in my client side code, when the respondent sends the provider key and username, the message goes to a _skipped exchange and I cannot get the response.

As far as I searched and understood, the Command and Event interfaces must be shared between the two projects (requester and respondent), but I since I am coding my project API-based, I do not want them to share the namespaces! How is it possible to overcome such a limitation in MassTransit?

Thanks so much

来源:https://stackoverflow.com/questions/51626266/does-masstransit-request-response-need-common-dlls-in-microservice-architectur

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!