如何从依赖注入类中接收IHubContext?

时间:2019-04-23 11:10:17

标签: asp.net-core signalr signalr-hub asp.net-core-signalr

我想在发生某些事件时使用SignalR从服务A 发送消息(例如,收到来自服务B 的消息)。 因此,需要从某种处理程序中调用集线器方法,而该处理程序不是使用依赖注入构造的。我该怎么做?

到目前为止,我尝试并阅读了以下内容:

  1. 我可以将上下文注入Controller并将其引向我的处理程序。我可能可以做到,但是将集线器上下文从顶部(控制器类)传递到底部(处理程序类)并不是最好的方法,这会给不应了解此上下文的类增加很多依赖关系,因此我希望避免这种情况。
  2. 我可以注入IHubContext in "any" class,但问题是,如何在处理程序上获取该类的实例?
  3. 将静态方法添加到具有注入上下文的类!好吧,直到您有1个客户端,该方法才起作用,因为使用新客户端时,静态属性将被覆盖。

所以我无法想象,处理程序如何使用依赖注入的IHubContext。

可能有人曾经这样做过,并有一个示例说明了如何将上下文真正注入 any 类。

在此先感谢您,并在需要时提供其他信息。

1 个答案:

答案 0 :(得分:1)

答案1

这是一种可能的解决方案。实施工厂模式。创建一个知道如何创建处理程序的工厂。在工厂中注入IHubContext。您可以通过这种方式使用一些方法:

  1. 通过传入IHubContext构造处理程序
  2. 在处理程序中创建一个公共属性,并设置IHubContext
  3. 在处理程序中创建一个方法,并将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();
    }
}

然后,您可以在其他方法中使用该_handler。我希望这会有所帮助。

答案2

另一种可能的解决方案是,如果可能的话,请使用IHostedService。请查看David Fowler issue提供的GitHub here解决方案,我认为这与您的情况有些相关。