SignalR Dependency Resolver не работает с концентраторами Javascript

Недавно я обновился до новой версии превосходной библиотеки SignalR и перенес всю свою инъекцию зависимостей из StructureMap в Ninject, поскольку Ninject, похоже, лучше поддерживается.

У меня есть внедрение зависимостей, которое отлично работает для уведомлений на стороне сервера, используя «Вещание через концентратор из-за пределов концентратора», описанное здесь: https://github.com/SignalR/SignalR/wiki/Hubs.

Проблема, которую я получаю, заключается в том, что все сообщения SignalR, исходящие из концентратора Javascript, похоже, не запускают внедрение зависимостей.

Я также использую MVC4 WebAPI, который также требует некоторой обуви, чтобы заставить работать внедрение зависимостей.

Вот мой Хаб:

public class PresenceHub : Hub, IPresenceHub
{
    private readonly IUserRepository _userRepository;
    private readonly IFormsAuthenticationProvider _formsAuthenticationProvider;

    public PresenceHub(IFormsAuthenticationProvider formsAuthenticationProvider, IUserRepository userRepository)
    {
        _userRepository = userRepository;
        _formsAuthenticationProvider = formsAuthenticationProvider;
    }

    public void PresenceChange(string presence)
    {
        var user = _userRepository.FindById(_formsAuthenticationProvider.GetUserId());
        var rosterEntry = Mapper.Map<User, RosterEntryDto>(user);
        rosterEntry.Presence = presence;
        Clients.updatePresence(rosterEntry);
    }
}

Вот мой загрузчик Ninject:

Namespace SLx.Web.App_Start
{
using System;
using System.Web;

using Microsoft.Web.Infrastructure.DynamicModuleHelper;

using Ninject;
using Ninject.Web.Common;

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        // SignalR Ninject Resolver
        GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);

        // WebApi Ninject Resolver
        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

        RegisterServices(kernel);
        return kernel;
    }


    private static void RegisterServices(IKernel kernel)
    {

    }        
}

Я уведомляю клиентов на стороне сервера через PresenceProxy, определенный следующим образом:

public class PresenceHubProxy : IPresenceHubProxy
{
    private readonly IHubContext _hubContext;

    public PresenceHubProxy()
    {
        _hubContext = GlobalHost.ConnectionManager.GetHubContext<PresenceHub>();
    }

    public void NotifyLogin(RosterEntryDto user)
    {
        _hubContext.Clients.updatePresence(user);
    }

    public void NotifyLogout(RosterEntryDto user)
    {
        _hubContext.Clients.updatePresence(user);
    }
}

Прокси-сервер отлично работает, внедряется в контроллеры или их зависимости и может отправлять сообщения клиентам.

Когда клиенты пытаются вызвать SignalR через Javascript, я получаю следующую ошибку:

No parameterless constructor defined for this object.

Похоже, Ninject не вызывается, потому что зависимости не внедряются в конструктор. Что мне нужно сделать, чтобы внедрение зависимостей работало и для вызовов Javascript?

Обновлять --

Следуя совету DFowler, я заменил Resolver в PostApplicationStart. Отладка В окне Immediate я вижу, что SignalR.GlobalHost.Resolver имеет тип NinjectDependencyResolver, но он все еще не работает. Я получаю ту же ошибку - нет конструктора без параметров.

Затем я удалил библиотеку NuGet NinjectDependencyResolver и добавил исходный файл в свое решение, и я использую его для целей отладки. Отладка GetService и GetServices показывает, что ни один метод никогда не вызывается в NinjectDependencyResolver.

Любые идеи?


person reach4thelasers    schedule 12.06.2012    source источник


Ответы (2)


Проблема была в том, что я не вызвал RouteTable.Routes.MapHubs:

GlobalHost.DependencyResolver = new SignalRNinjectResolver(NinjectWebCommon.Kernel);
RouteTable.Routes.MapHubs(new SignalRNinjectResolver(NinjectWebCommon.Kernel));
person reach4thelasers    schedule 13.06.2012

Из документов https://github.com/SignalR/SignalR/wiki/Extensibility:

ПРИМЕЧАНИЕ. НЕ переопределяйте глобальный преобразователь в PreApplicationStart, он не будет работать или будет работать только иногда. Сделайте это в PostApplicationStart (используя WebActivator) или в Global.asax.

person davidfowl    schedule 12.06.2012