如何在具有其他构造函数参数的类内检索HubContext(SignalR)?

时间:2018-10-15 19:22:03

标签: c# asp.net-core constructor signalr

我有一个在构造函数中有一些参数的类。

public class ServerStatus
    {   
       private int idserver;
       private string des;
       private string ipserver;

       private int attemptfailded = 0;

        public ServerStatus(int id, string description, string ip)
        {
            this.idserver = id;
            this.des = description;
            this.ipserver = ip;    
        }

       ... /* Other logic of this class: like notification management */

    }

现在,我想在此类中添加一个这样的中心上下文实例,并有一个使用该中心上下文的方法。

public class ServerStatus
{
   private readonly IHubContext<MyHub, ITypedHubClient> _hubContext;

   private int idserver;
   private string des;
   private string ipserver;

   private int attemptfailded = 0;

    public ServerStatus(IHubContext<MyHub, ITypedHubClient> hubContext, int id, string description, string ip)
    {
        this.idserver = id;
        this.des = description;
        this.ipserver = ip;
        _hubContext = hubContext;

    }

   ...

   public async Task SendMessageToClients()
   {       
        await _hubContext.Clients.All.BroadcastMessage("Server", 
        "ServerDown");
   }

}

尤其是,我希望该类在任何地方都可以实例化,例如,如果我有另一个实现此ServerStatus对象列表的类,则需要从该类中调用构造函数。这是一个示例:

public static class MyClass
{

    public static List<ServerStatus> servers = new List<ServerStatus>();

    public static void initializeServers()
    {
        foreach (/* server I have in a Database */)
        {

            ServerStatus s = new ServerStatus (/* the hub context and the parameters of the server */)

            servers.Add(s);
        }
    }
}

我的问题是:如何将这个hubContext添加到我的课程中,并在需要它们的地方实例化这些对象。

请记住,我已经设置了所有SignalR库,并且可以使用,但是现在我不明白如何将hubContext传递给需要它的类。

1 个答案:

答案 0 :(得分:2)

您的课程需要静态吗?

ConfigureServices中注册类/服务时,它们会注册到.NET Core Service Provider。使用非静态类,您可以注入此接口,并将其用于向.NET Core Service Provider请求注册的服务,例如

public class MyClass
{
    private readonly IServiceProvider _provider;

    public MyClass(IServiceProvider provider)
    {
        _provider = provider;
    }

    public void InitializeServers()
    {
        foreach(/* server I have in database */)
        {
            var hub = _provider.GetService<IHubContext<MyHub, ITypedHubClient>>();

            ServerStatus s = new ServerStatus(hub, ...);
        }
    }
}

您可以使用IServiceProvider来检索已向其注册的所有服务,包括您的IHubContext。 在内部,.NET Core在创建服务时使用服务提供商将服务注入到您注册的服务/控制器等中。在这种情况下,您只是手动执行相同的操作。

注意: 您需要在MyClass中注册startup.cs,服务提供商才能注入到构造函数中。例如:

services.AddSingleton<MyClass>();

但是,现在您已经向服务提供商注册了MyClass,您可以直接将依赖项注入MyClass

public class MyClass
{
    private readonly IHubContext<MyHub, ITypedHubClient> _hubContext;

    public MyClass(IHubContext<MyHub, ITypedHubClient> hubContext)
    {
        _hubContext = hubContext;
    }

    public void InitializeServers()
    {
        foreach(/* server I have in database */)
        {
            ServerStatus s = new ServerStatus(_hubContext, ...);
        }
    }
}

如果您想在启动时实例化此类,则可以使用Configure方法来获取实例。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var myClass = app.ApplicationServices.GetService<MyClass>();

    myClass.InitializeServers();

    // the rest of the startup
    ...
}

ApplicationServices是我们前面提到的IServiceProvider接口的实现。

GetService的调用可以在Configure方法中的任何地方进行。不必一开始就正确。