У меня такая проблема выбора дизайна и как-то неопрятно, но напрасно. Это работает только в определенном c сценарии.
Я пытаюсь опубликовать sh и использовать сообщение в MassTransit. Пример: (Publisher - простое консольное приложение)
IShape message = GetShape(/**Business Logic will return some concrete object (Circle or square) based on some business inputs**/);
bus.Publish(message);
(Потребители - CircleConsumer и SquareConsumer)
class CircleConsumer : IConsumer<IShape>
{
public Task Consume(ConsumeContext<IShape> context)
{
var circle = context.Message as Circle;
return Task.CompletedTask;
}
}
class SquareConsumer : IConsumer<IShape>
{
public Task Consume(ConsumeContext<IShape> context)
{
var square = context.Message as Square;
return Task.CompletedTask;
}
}
(Конфигурация потребителей в. Net Базовый проект размещенной службы)
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>()
.AddScoped<SquareConsumer>()
.AddScoped<CircleConsumer>()
.AddMassTransit(cfg =>
{
cfg.AddBus(ConfigureBus);
cfg.AddConsumer<SquareConsumer>();
cfg.AddConsumer<CircleConsumer>();
})
.AddSingleton<IBus>(provider => provider.GetRequiredService<IBusControl>())
.AddSingleton<IHostedService, TestMTConsumerHostedService>();
IBusControl ConfigureBus(IServiceProvider provider)
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(hostContext.Configuration["RabbmitMQ:Server:Host"], hostContext.Configuration["RabbmitMQ:Server:VirtualHost"], h =>
{
h.Username(hostContext.Configuration["RabbmitMQ:Auth:Username"]);
h.Password(hostContext.Configuration["RabbmitMQ:Auth:Password"]);
});
cfg.ReceiveEndpoint("CircleQueue", ep =>
{
ep.PrefetchCount = 16;
ep.UseMessageRetry(r => r.Interval(2, 100));
ep.Consumer<CircleConsumer>(provider);
});
cfg.ReceiveEndpoint("SquareQueue", ep =>
{
ep.PrefetchCount = 16;
ep.UseMessageRetry(r => r.Interval(2, 100));
ep.Consumer<SquareConsumer>(provider);
});
});
}
});
Мое требование - опубликовать Publisher sh сообщение без знания конкретных классов. И только один из потребителей получает сообщение в зависимости от типа сообщения.
Но похоже, что оба получателя получают сообщение, а также приведение не работает. Желаемый: Предположим, что когда издатель отправляет объект Square, вызов должен принимать только пользователь Square. Но в моем случае и SquareConsumer, и CircleConsumer получают сообщение.
В качестве обходного пути это работает:
Всегда публикуется sh конкретные объекты.
bus.Publish(new Square());
Объявите потребителей с конкретными типами.
class CircleConsumer : IConsumer<Circle>
{
public Task Consume(ConsumeContext<Circle> context)
{
var circle = context.Message;
return Task.CompletedTask;
}
}
class SquareConsumer : IConsumer<Square>
{
public Task Consume(ConsumeContext<Square> context)
{
var square = context.Message;
return Task.CompletedTask;
}
}
Но было бы здорово, если бы я мог сделать это в общем.
Есть предложения?