0
votes

We use Ninject as a DI container for Signalr. I can't seem to get the ITransportHeartbeat injected into one of my classes. I use this interface to manage the client presence as recommended by Signalr.

   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));
        }
    }

Startup.cs

 public void Configuration(IAppBuilder app)
 {
      var kernel = GetKernel();
      var resolver = new NinjectSignalRDependencyResolver(kernel);
      var config = new HubConfiguration { Resolver = resolver }
      GlobalHost.DependencyResolver = resolver;
      GlobalHost.HubPipeline.AddModule(kernel.Get<ErrorModule>());
      app.MapSignalR(config);

      var bootstrapper = new Bootstrapper();
        bootstrapper.Initialize(() =>
        {
            return kernel;
        });

        ///monitor1 is set to null
        var monitor1=GlobalHost.DependencyResolver.Resolve<IMyClass>();
        //monitor2 is set to null 
        var monitor2=_kernel.Get<IMyClass>();
  }

My custom Ninject bindings:

    private IKernel GetKernel()
    {
        if (_kernel != null) return _kernel;
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
        kernel.Load(new HubModule());
        kernel.Load(new LogModule());
        kernel.Load(new DaoModule());
        return kernel;
    }

My own class:

 Public class MyClass : IMyClass
 {  
     ITransportHeartbeat _heartbeat;
     IClientListDao _clientList;

     MyClass(IClientListDao clientList, ITransportHeartbeat heartbeat)
     {
        _hearbeat=heartbeat;
        _clientList=clientList;
     }
     .
     .
  }

In MyClass above, Ninject injects the object for IClientDao but not for ITransportHeartbeat. I am not binding this interface to anything as this is done by the default resolver. What I am doing wrong here? Why doesn't the default resolver inject an object for the ITransportHeartbeat?

1

1 Answers

0
votes

I ended up manually resolving the ITransportHeartbeat in startup.cs:

var myClass=kernel.Get<IMyClass>(
        new ConstructorArgument("heartbeat", resolver.Resolve<ITransportHeartbeat>()));

If I understand it correctly, ITransportHeartbeat is resolved by the default dependency resolver. So when I do kernel.Get<IMyClass>() without passing any constructor arguements, Ninject would resolve the IClientListDao and the default dependency resolver resolves the ITransportHeartbeat. But the latter is not resolved.