У меня есть ASP.NET Web API, использующий MediatR и SimpleInjector.
Они зарегистрированы так:
_container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
_container.Options.DefaultLifestyle = Lifestyle.Scoped;
_container.Collection.Register(typeof(INotificationHandler<>), typesFound);
Я могу публиковать события из моего Controllers
:
[HttpGet]
public ActionResult<...> Get()
{
_mediator.Publish(new SomeEvent());
}
Это прекрасно работает!
Новым требованием является прослушивание обновлений из внешней системы (Tibco). Когда происходит обновление, уведомление приходит через событие C # из другого потока. В обработчике событий C # я хочу использовать MediatR для Publish
уведомления:
void callbackFromTibco(object listener, MessageReceivedEventArgs @args)
{
_mediatr.Publish(new SomeEvent();
}
Именно в этот момент SimpleInjector выдает исключение:
SomeEventHandler is registered as 'Async Scoped' lifestyle, but the instance is requested outside the context of an active (Async Scoped) scope
.
Это потому, что стек вызовов происходит из другого потока, тогда как в Controller
сам контроллер был ограничен SimpleInjector, и, следовательно, MediatR создает обработчик в той же области.
Можно ли что-то сделать, чтобы я мог зарегистрировать обработчики событий для использования в обоих случаях?
Я справился с этим, создав интерфейс IPublishEvents
и класс PublishEvents
, где класс PublishEvents
выглядит следующим образом:
public PublishEvents(Container container, IMediator mediator)
{
_container = container;
_mediator = mediator;
}
public Task Publish(object notification, CancellationToken cancellationToken = default)
{
using (AsyncScopedLifestyle.BeginScope(_container))
{
return _mediator.Publish(notification, cancellationToken);
}
}
Является ли абстракция правильным подходом? Это, конечно, соответствует Don't Marry the Framework
мантре, но кроме этого, я хотел бы знать, есть ли лучший способ ...