3

私は最近、優れた SignalR ライブラリの新しいバージョンにアップグレードし、すべての依存性注入を StructureMap から Ninject に移動しました。Ninject の方がサポートされているようです。

https://github.com/SignalR/SignalR/wiki/Hubsで説明されている「ハブの外部からハブを介したブロードキャスト」を使用して、サーバー側の通知に対して依存性注入が正常に機能しています。

私が得ている問題は、Javascript ハブから発信されたすべての SignalR メッセージが依存性注入をトリガーしていないように見えることです。

私は 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 Bootstrapperです:

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

プロキシは正常に動作し、コントローラーまたはその依存関係に挿入され、クライアントにメッセージを送信できます。

クライアントが Javascript 経由で SignalR を呼び出そうとすると、次のエラーが発生します。

No parameterless constructor defined for this object.

依存関係がコンストラクターに注入されていないため、Ninject が呼び出されていないようです。依存性注入を Javascript 呼び出しでも機能させるにはどうすればよいですか?

アップデート -

DFowler からのアドバイスに従って、PostApplicationStart の Resolver を置き換えました。デバッグイミディエイト ウィンドウで、SignalR.GlobalHost.Resolver のタイプが NinjectDependencyResolver であることがわかりますが、まだ機能していません。同じエラーが発生します。パラメーターのないコンストラクターはありません。

次に、NinjectDependencyResolver NuGet ライブラリを削除し、ソース ファイルをソリューションに追加して、それをデバッグ目的で使用しています。GetService と GetServices でデバッグすると、どちらのメソッドも NinjectDependencyResolver で呼び出されないことがわかります。

何か案は?

4

2 に答える 2

3

問題は、RouteTable.Routes.MapHubs を呼び出していなかったことです。

GlobalHost.DependencyResolver = new SignalRNinjectResolver(NinjectWebCommon.Kernel);
RouteTable.Routes.MapHubs(new SignalRNinjectResolver(NinjectWebCommon.Kernel));
于 2012-06-13T16:58:40.230 に答える
2

ドキュメントからhttps://github.com/SignalR/SignalR/wiki/Extensibility

注:PreApplicationStartでグローバルリゾルバーをオーバーライドしないでください。オーバーライドしないか、たまにしか機能しません。PostApplicationStart(WebActivatorを使用)またはGlobal.asaxで実行します。

于 2012-06-12T19:19:43.653 に答える