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?
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.
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With