How can I set up SignalR Hub Dependency Injection in ASP.NET 5 (vNext)?

15,059

Solution 1

I managed to resolve this by adding my State class as a Singleton for IState in Startup.ConfigureServices, and then making a ServiceProvider property publicly available on my Startup.cs class. From there, I was able to GetRequiredService within the constructor of my SignalR Hub class. It isn't the ideal solution and hopefully I'll be able to adjust this to use constructor/property injection as the platform reaches RC.

Here's my code:

Startup.cs

public static IServiceProvider __serviceProvider;

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR();
    services.AddSingleton<IState, State>();
    __serviceProvider = services.BuildServiceProvider();
}

public void Configure(IApplicationBuilder app)
{
    app.UseSignalR();
}

MyHub.cs

public class MyHub : Hub
{
    public IState State { get; set; }

    public MyHub()
    {
        State = (IState) Startup.__serviceProvider.GetRequiredService(typeof (IState));
    }

    public override Task OnConnected()
    {
        State.Clients = Clients;
        State.Groups = Groups;
        return base.OnConnected();
    }
}

In this way, I was able to set properties and call methods on IState implementing objects from within MyHub, allowing me to persist my app state in memory.

Solution 2

the best way (for Asp.Net 5) create a custom resolver to DefaultDependencyResolver that receives IServiceProvider:

 public class CustomSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IServiceProvider _serviceProvider;

    public CustomSignalRDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override object GetService(Type serviceType)
    {
        var service = _serviceProvider.GetService(serviceType);

        return service ?? base.GetService(serviceType);
    }


}

Then on StartUp class

 public void ConfigureServices(IServiceCollection services)
    {

         services.AddSingleton<IState, State>();

        //... other services


        GlobalHost.DependencyResolver = new CustomSignalRDependencyResolver(services.BuildServiceProvider());

    }
Share:
15,059
Martin Tracey
Author by

Martin Tracey

Updated on July 20, 2022

Comments

  • Martin Tracey
    Martin Tracey almost 2 years

    Trying to do dependency injection into my SignalR Hub class using the SignalR-Server which is part of ASP.NET 5 (repo). I tried to figure this out from the tutorial at this link but I can't seem to identify how I can do this given that GlobalHost is no longer available. Here's what I'm trying to do:

    Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSignalR();
        services.AddSingleton<IState, State>();
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseSignalR();
    }
    

    MyHub.cs

    public class MyHub : Hub
    {
        public IState State { get; set; }
    
        // SignalR accepts this parameterless ctor
        public MyHub()
        {
        }
    
        // SignalR won't use this because it has a parameter
        public MyHub(IState state)
        {
            State = state;
        }
    }
    

    How can I get SignalR-Server to use the MyHub(IState state) constructor injecting the required dependencies?

  • Martin Tracey
    Martin Tracey over 8 years
    Unfortunately, it looks like I can't set the Resolver property in SignalR-Server either! :( I had tried it before I came here too. Back to the drawing board, I guess. Thanks though!
  • radu-matei
    radu-matei over 8 years
    Updated the answer. Hope it helps!
  • radu-matei
    radu-matei over 8 years
  • Admin
    Admin almost 5 years
    What about the issue on SignalR dependency injection using Ninject? Any idea about that? Thanks in advance...