Как внедрить массового потребителя зависимостей в контейнер windsor

#dependency-injection #castle-windsor #ioc-container #masstransit

#внедрение зависимостей #castle-Виндзор #ioc-контейнер #masstransit

Вопрос:

Как использовать внедрение зависимостей в классе consumer. Я получаю сообщение об ошибке как «Тип ‘Esb.Masstransit.RabbitMQ.Application.IEventConsumerService’ не может использоваться в качестве параметра типа ‘TConsumer’ в универсальном типе или методе ‘MassTransit.Расширения потребителей.Потребитель (массовый переход.IReceiveEndpointConfigurator, System.ДействиеНастройки потребления.IConsumerConfigurator>)’. Нет неявного преобразования ссылки из ‘Esb.Masstransit.RabbitMQ.Application.IEventConsumerService’ to ‘MassTransit.IConsumer'»

Это класс контейнера

 container.Register(Component.For<IEventConsumerService>().ImplementedBy<EventConsumerService>().LifestyleSingleton());
container.Register(Component.For<ICommandConsumerService>().ImplementedBy<CommandConsumerService>().LifestyleSingleton());

var busControl = Bus.Factory.CreateUsingRabbitMq(rabbit =>
        {
            var host = rabbit.Host(new Uri(rabbitMqHost), settings =>
            {
                settings.Password(rabbitMqUserName);
                settings.Username(rabbitMqPassword); 
            }); 

            rabbit.ReceiveEndpoint(host, eventQueue1, e =>
            {
                e.BindMessageExchanges = false; 
               e.Consumer<EventConsumerService>(); // I getting error here
                e.Bind(typeof(IPublishMessage).FullName.Split('.').LastOrDefault(), x =>
                {
                    x.RoutingKey = "1";
                    x.ExchangeType = ExchangeType.Direct;
                });
            }); 
        }); 
        container.Register(Component.For<IBus, IBusControl>().Instance(busControl));
  

Это класс Consumer

 public class EventConsumerService : BaseLogger, IEventConsumerService, IConsumer<IPublishMessage>
{
    private readonly ICommandConsumerService _service;

    public EventConsumerService(ICommandConsumerService service)
    {
        _service = service;
    }

    public Task Consume(ConsumeContext<IPublishMessage> context)
    {
        try
        { 
            Console.WriteLine("In event consumer "   context.MessageId   " _"   context.Message.MessageId   ", "   context.Message.Message   " "   context.Message.CreationDate);
            return Task.CompletedTask;
        }
        catch (Exception ex)
        {
           Logger.Error("EventConsumerService", ex);
        }
        return Task.CompletedTask;
    } 
}
  

Ответ №1:

Вы должны использовать пакет интеграции контейнера, MassTransit.CastleWindsor и настройте свой контейнер, как показано в документации.

Кроме того, потребители должны быть зарегистрированы как конкретные типы, а не интерфейсы.

На основе вашего примера:

 var container = new WindsorContainer();
container.AddMassTransit(x =>
{
    x.AddConsumer<EventConsumerService>();

    x.UsingRabbitMq(cfg =>
    {
        cfg.Host(new Uri(rabbitMqHost), settings =>
        {
            settings.Password(rabbitMqUserName);
            settings.Username(rabbitMqPassword); 
        }); 

        cfg.ReceiveEndpoint(eventQueue1, ec =>
        {
            ec.ConfigureConsumeTopology = false; 
            ec.Bind(typeof(IPublishMessage).FullName.Split('.').LastOrDefault(), b =>
            {
                b.RoutingKey = "1";
                b.ExchangeType = ExchangeType.Direct;
            });

            ec.ConfigureConsumer<EventConsumerService>(context);
        });
    });
});
  

Потребители не должны быть одноэлементными, они должны быть ограничены. Приведенный выше код зарегистрирует потребителя в контейнере для вас.