I have the following simple Hub Class to list users using a injected User Service. A startup class that uses the NinjectSignalRDependencyResolver. And very simple client script.
hub
[HubName("dashboardHub")]
public class DashboardHub : Hub
{
private readonly IUserService _users;
public DashboardHub(IUserService users)
{
_users = users;
}
public void Initialize()
{
var users = _users.ListUsers();
Clients.All.UpdateStatus(users);
}
}
startup.cs
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
var config = new HubConfiguration()
{
Resolver = resolver,
};
app.MapSignalR(config);
NinjectSignalRDependencyResolver
public class NinjectSignalRDependencyResolver : DefaultDependencyResolver
{
private readonly IKernel _kernel;
public NinjectSignalRDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public override object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
}
}
JavaScript
<script>
$(function () {
var dashboard = $.connection.dashboardHub;
dashboard.client.updateStatus = function (users) {
var elem= $('.userList');
elem.html('');
$.each(users, function (i, user) {
parent.append("<p>" user.Name + "<p>");
});
};
$.connection.hub.start().done(function () {
dashboard.server.initialize();
});
});
</script>
I register the Interface with Ninject in the stadard way inside RegisterServices
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUserService >().To<UserService>().InSingletonScope();
...
}
When open client with the script. The code runs and there are no exceptions or script errors generated. The Constructor of Dashboard is never called and neither is the Initialize() method - even though the object exists in the JavaScript and so does the method. The the user list is never populated as client.updateStatus is never called.
If I add a default constructor to the Hub class then this is called and so too is the Initialize method - but it obviously now falls over as the private IUserService variable is null.
public DashboardHub()
{
}
How do you configure SignalR 2.0 and Ninject to allow Hubs to have dependency Injected constructor arguments?
GlobalHost.DependencyResolver = new NinjectSignalRDependencyResolver(kernel);
? – Rui Jarimba