私は最近、優れた 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 で呼び出されないことがわかります。
何か案は?