Самостоятельное многоуровневое внедрение зависимостей SignalR2

Я только что реализовал DI с помощью Ninject для своего собственного проекта SignalR2.

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

И мой класс запуска:

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

В моем конструкторе концентратора сигналов я ожидаю IRealTimeDataEngine.

public MyHub(IRealTimeDataEngine realTimeDataEngine, IHistoricalDataEngine historicalDataEngine)

В моем хосте, который является консольным приложением, мне нужно внедрить тот же IRealTimeDataEngine.

public DummyProvider(IRealTimeDataEngine realTimeDataEngine)

В моем методе Main мне нужно создать объект DummyProvider.

Если я не ошибаюсь, создание нового ядра не дало бы мне один и тот же объект в двух разных проектах, так как же мне запрашивать один и тот же IRealTimeDataEngine в моем корне композиции?


person János Körömi    schedule 21.01.2018    source источник


Ответы (1)


Вы правы, вы должны использовать только одно ядро ​​для каждого приложения. Это означает, что в вашем случае вы должны создать свое ядро ​​вне класса Startup. Этого можно добиться, используя перегруженный вызов метода WebApp.Start, например:

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

       ...
person Jan Muncinsky    schedule 22.01.2018