DI горе с потребителем Mass Transit и простым инжектором - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть .net core web api, к которому я пытаюсь добавить потребителя Mass Transit.Потребитель зависит от услуги.Сервис зарегистрирован в контейнере Simple Injector.

container.Register<IMyService, MyService>(Lifestyle.Scoped); 

Служба, в свою очередь, имеет зависимость от DBContext, который был добавлен с помощью IServiceCollection.AddDbContext, а затем был перекрестным образом:

Container.CrossWire<MyDbContext>(app);  

Я добавил службу вконструктор потребителя выглядит так:

public AddMyCommandConsumer(IMyService service)
{
    _service = service;                
}

Так что моим следующим шагом была настройка конечной точки.Сначала попробуйте так:

cfg.ReceiveEndpoint(host, options.MyQueue, e =>
{
    var service = container.GetService<IMyService>();
    e.Consumer(() => new AddMyCommandConsumer(service));
}

Сбой при сбое из-за того, что служба имеет асинхронную область.Простому инжектору это не понравилось.Так что после небольшого копания я придумал вторую итерацию:

cfg.ReceiveEndpoint(host, options.MyQueue, e =>
{
    using (AsyncScopedLifestyle.BeginScope(container))
    {
        var service = container.GetService<IMyService>();
        e.Consumer(() => new AddMyCommandConsumer(service));
    }
}

Это немного дальше, с созданием потребителя и вызовом метода потребления, но как только я используюсервис и DBContext необходимы, простой инжектор жалуется, что DBContext был удален.Если я удаляю оператор , используя , он работает, но область действия никогда не удаляется.

Затем я взглянул на пакет nuget MassTransit.SimpleInjector.Нет документации и примеров, которые я могу найти, но после небольшого копания я пришел к следующему:

var consumerFactory = new ScopeConsumerFactory<AddMyCommandConsumer>(new 
    SimpleInjectorConsumerScopeProvider(container));                        
e.Consumer(consumerFactory);

Mass Transit пытается создать потребителя, но на этот раз это не удается, поскольку Simple Injector являетсяневозможно создать сервис, даже если он зарегистрирован в контейнере.Эта последняя попытка, как я уже сказал выше, немного догадывается, документации или примеров нет.Честно говоря, я думаю, что даже если бы я заработал это, я столкнулся бы с той же проблемой с DBContext, что и выше.

Есть идеи?

1 Ответ

0 голосов
/ 14 февраля 2019

Добавьте ссылку на пакет MassTransit.SimpleInjector, а затем в конечной точке получения настройте получателя, используя:

cfg.ReceiveEndpoint("queue_name", e =>
{
    e.Consumer<AddMyCommandConsumer>(container);
});

Метод расширения правильно настроит поставщика области и добавит фабрику потребителя для извлечения.из контейнера.Ваш потребитель должен быть зарегистрирован как AsyncScoped, чтобы он правильно обрабатывал async / await (MT в значительной степени построен на TPL).

container.Register<AddMyCommandConsumer>(Lifestyle.Scoped);

Кроме того, я думаю, что есть опция контейнера для определения асинхронного образа жизни какdefault.

container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

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

...