Не удается заставить EventAggregator работать с AutoFac в ASP.NET

#asp.net-mvc #autofac #mediatr #eventaggregator

#asp.net-mvc #autofac #mediatr #eventaggregator

Вопрос:

Мне нужен простой EventAggregator в моем ASP.NET Приложение MVC, в котором я использую AutoFac. Я взглянул на https://github.com/NimaAra/Easy.MessageHub — Мне очень нравится простота и легкий вес, поскольку я чувствую, что полная реализация сервисной шины может быть излишней для моих нужд. Но я весь внимание, если у кого-то есть лучший подход 🙂

Однако, похоже, я не могу настроить настройку для работы с моим веб-приложением. У меня очень простая настройка:

HomeController (просто для инициирования вызова)

 public class HomeController : Controller
    {
        private readonly IPublishStuffService _publishStuffService;
        private readonly IMessageHub _hub;

        public HomeController(IPublishStuffService publishStuffService, IMessageHub hub)
        {
            _publishStuffService = publishStuffService;
            _hub = hub;

            _hub.RegisterGlobalHandler((type, eventObject) => Debug.WriteLine($"Type: {type} - Event: {eventObject}"));
        }

        public ActionResult Index()
        {
            _publishStuffService.PublishStuff("Hello world");
            return View();
        }

    }
  

PublishStuffService

 public class PublishStuffService : IPublishStuffService
    {
        private readonly IMessageHub _hub;

        public PublishStuffService(IMessageHub hub)
        {
            _hub = hub;
        }

        public void PublishStuff(string message)
        {
            _hub.Publish(message);
        }
    }
  

SubscribeToStuffService

 public class SubscribeToStuffService : ISubscribeToStuffService
    {
        private readonly IMessageHub _hub;

        public SubscribeToStuffService(IMessageHub hub)
        {
            _hub = hub;
            _hub.Subscribe<string>(HandleSubscription);
        }

        public void HandleSubscription(string message)
        {
            Debug.WriteLine("===================");
            Debug.WriteLine(message);
            Debug.WriteLine("===================");
        }
    }
  

Мой GlobalHandler нормально выводит сообщение «Hello world», но моя служба подписки никогда не вызывается. Я полагаю, что это может быть проблемой с моей настройкой AutoFac, но я не уверен, как справиться с ситуацией.

Моя конфигурация AutoFac (с использованием AutoFac.MVC5) выглядит следующим образом:

 var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(HomeController).Assembly);

builder.RegisterModelBinders(typeof(HomeController).Assembly);
builder.RegisterModelBinderProvider();

builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterSource(new ViewRegistrationSource());
builder.RegisterFilterProvider();

// Register individual components
builder.RegisterType(typeof(SubscribeToStuffService)).As<ISubscribeToStuffService>().InstancePerLifetimeScope();
builder.RegisterType(typeof(PublishStuffService)).As<IPublishStuffService>().InstancePerLifetimeScope();
builder.RegisterType(typeof(MessageHub)).As<IMessageHub>().SingleInstance();

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
  

Кто-нибудь может помочь мне выяснить, как обеспечить сохранение концентратора сообщений во всем моем веб-приложении, чтобы у меня были разные классы, подписывающиеся на разные события, опубликованные в концентраторе сообщений.
По сути, я ищу часть уведомлений библиотеки Mediatr Джимми Богарда, которая, кстати, работает идеально, но я чувствую, что реализация Mediatr может быть немного сложной, если я собираюсь использовать только настройку уведомлений 🙂

ОБНОВЛЕНИЕ Я действительно могу запустить события подписчика, если добавлю зависимость к ISubscribeToStuffService в том же месте, где я публикую (здесь, в моем HomeController):

 public class HomeController : Controller
    {
        private readonly IPublishStuffService _publishStuffService;
        private readonly IMessageHub _hub;
        private readonly ISubscribeToStuffService _subscribeToStuffService;

        public HomeController(IPublishStuffService publishStuffService, IMessageHub hub, ISubscribeToStuffService subscribeToStuffService)
        {
            _publishStuffService = publishStuffService;
            _hub = hub;
            _subscribeToStuffService = subscribeToStuffService;
        }
        ...
    }
  

Это, по-видимому, устраняет подписчика. Но это не очень полезно, поскольку это противоречит цели иметь слабую связь между моими зависимостями.

Итак, возникает вопрос: как мне заставить AutoFac разрешать моих подписчиков без необходимости добавлять их в качестве зависимостей везде, где я публикую что-то в шине сообщений? Можно ли это сделать?

В ОБНОВЛЕНИИ 2 найдено это изящное маленькое расширение pub / sub для AutoFac: https://github.com/jonstelly/AutofacEvents . Он делает все, что мне нужно, прямо из коробки с точки зрения запуска и запуска агрегатора событий с AutoFac.

Комментарии:

1. Здесь отсутствует некоторая информация. Я никогда не использовал EventAggregator, но вы не показываете людям, где на самом ISubscribeToStuffService деле используется / создается экземпляр. Из этого… не похоже, что он когда-либо используется, и если он никогда не создается (и, я бы предположил, активен при публикации сообщения), то он не будет реагировать на событие, верно? Может быть? Опять же, я не специалист по EventAggregator, поэтому, вероятно, здесь не смогу помочь.

2. Идея состоит в том, чтобы не создавать тесную связь между различными частями приложения. Таким образом, в основном концентратор сообщений / служебная шина (как бы вы ее ни называли) должна содержать информацию о событиях, публикуемых в нем, — и затем подписчики должны автоматически вызываться — без необходимости их использования. Таким образом, в принципе, я мог бы выполнить несколько разных действий при возникновении события (например, при событии «Пользователь создан» я мог бы отправить пользователю приветственное электронное письмо, а также уведомление в бухгалтерию).). Но я не могу заставить подписчиков подключиться к AutoFac:(

3. @TravisIlligbut вы правы в результате (и, вероятно, также в причине) — ISubscribeToStuff (и любые другие подписчики), похоже, не являются «живыми» или инициированными. Но я предполагаю, что это потому, что я неправильно настроил свой IoC, чтобы это работало (или у кого-то еще может быть лучшее предложение).

4. Это вопрос дизайна приложения, а не IoC. В обязанности Autofac не входит выяснять, как и когда нужно создавать экземпляры ваших подписчиков — это код приложения. Когда вам нужны экземпляры из кода вашего приложения — это IoC.