Reputation: 54
I've just implemented DI using Ninject for my self-hosted SignalR2 project.
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));
}
}
And my Startup class:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
kernel.Bind<MyDbContext>().ToSelf();
kernel.Bind<IRealTimeDataEngine>().To<RealTimeDataEngine>().InSingletonScope();
kernel.Bind<IHistoricalDataEngine>().To<HistoricalDataEngine>().InSingletonScope();
kernel.Bind(typeof(IHubConnectionContext<dynamic>)).ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<MyHub>().Clients
).WhenInjectedInto<IRealTimeDataEngine>();
var config = new HubConfiguration {Resolver = resolver};
ConfigureSignalR(app, config);
}
public static void ConfigureSignalR(IAppBuilder app, HubConfiguration config)
{
app.MapSignalR(config);
}
}
In my signalr hub constructor I expect an IRealTimeDataEngine.
public MyHub(IRealTimeDataEngine realTimeDataEngine, IHistoricalDataEngine historicalDataEngine)
In my host, which is a console application, I need the same IRealTimeDataEngine to be injected.
public DummyProvider(IRealTimeDataEngine realTimeDataEngine)
In my Main method I need to create a DummyProvider object.
If I'm not mistaken, creating a new kernel would not give me the same object in the two different projects, so how should I ask for the same IRealTimeDataEngine at my composition root?
Upvotes: 1
Views: 76
Reputation: 4418
You're right you must use only one kernel per application. That means you should create your kernel outside of Startup
class in your case. This can be achieved by using overloaded call of WebApp.Start
method like:
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
var server = WebApp.Start("http://localhost:8080/", (appBuilder) =>
{
var resolver = new NinjectSignalRDependencyResolver(kernel);
var config = new HubConfiguration {Resolver = resolver};
...
});
...
Upvotes: 1