Как получить IHubContext из классов Dependency Injected? - PullRequest
0 голосов
/ 23 апреля 2019

Я хочу отправить сообщение от Сервиса A , используя SignalR, когда происходит какое-либо событие (например, получено сообщение от Сервис B ).Таким образом, метод-концентратор должен вызываться из какого-то рода обработчика, который не создан с использованием Dependency Injection.Как я могу это сделать?

До сих пор я пробовал и читал о следующих вещах:

  1. Я могу вставить контекст в Controller и привести его к своему обработчику.Я, вероятно, могу это сделать, но передача контекста хаба сверху (класс контроллера) снизу (класс обработчика) - не лучший подход, который добавляет множество зависимостей к классам, которые не должны знать об этом контексте, поэтому яЯ хотел бы избежать этого.
  2. Я могу внедрить свой IHubContext в «любой» класс , но, с другой стороны, как получить экземпляр этого класса в моем обработчике?
  3. Добавить статический метод в класс с внедренным контекстом !?Хорошо, это работает, пока у вас не будет 1 клиента, потому что с новым клиентом статическое свойство будет перезаписано.

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

Возможнокто-то делал это раньше и имеет пример того, как действительно внедрить контекст в любой класс.

Заранее спасибо, и любая дополнительная информация будет предоставлена, если необходимо.

1 Ответ

1 голос
/ 23 апреля 2019

Ответ 1

Вот одно из возможных решений.Реализуйте фабричный шаблон.Создайте фабрику, которая знает, как создать ваш обработчик.Введите IHubContext на заводе.Вы можете использовать несколько подходов таким образом:

  1. Создайте обработчик, передав IHubContext
  2. Создайте открытое свойство в обработчике и установите IHubContext
  3. Createметод в обработчике и передайте IHubContext в качестве параметра

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

public interface IHandlerFactory
{
   Handler CreateHandler();
}

public class HandlerFactory : IHandlerFactory
{
    private IHubContext _hubContext;

    public HandlerFactory(IHubContext context)
    {
        _hubContext = context;
    }
    public Handler CreateHandler()
    {
        return new Handler(param1, param2, _context);
    }    
}

Затем в точке входа, контроллер / сервис, введите фабрику через DI

public class MyController : Controller
{
    private Handler _handler;

    public MyController(IHandlerFactory factory)
    {
        _handler = factory.CreateHandler();
    }
}

Затем вы можете использовать этот обработчик _ в других методах.Надеюсь, это поможет.

Ответ 2

Другое возможное решение - использовать IHostedService, если это вообще возможно для вас.Пожалуйста, ознакомьтесь с решением проблемы GitHub , предоставленной Дэвидом Фаулером здесь , которое, я думаю, имеет отношение к вашему сценарию.

...