SignalR Problèmes avec SignalR.Ninject et sur-levant IconnectionIdFactory
Question
J'ai tous les bits NuGet pour Signalr, j'essaie d'utiliser mes propres clients ainsi que le conteneur d'injection de dépendance qui est livré avec SignalR pour tous mes autres référentiels et autres. Maintenant, la chose étrange est que cette jQuery pour se connecter au hub échoue:
debugger;
// Proxy created on the fly
var chat = $.connection.chat;
Fondamentalement, l'objet de chat devient non défini comme si le signal ne pouvait pas être résolu. Cela a commencé à se produire une fois que j'ai essayé de sureacher le résolveur par défaut pour SignalR avec le code ci-dessous.
Qu'est-ce que j'oublie ici?
Un autre problème que j'ai est que je ne sais pas si mon userLIentidFactory qui implémente IconnectionIdFactory fonctionne non plus.
Voici le code MVC3 dans mon Global.asax
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<UserIdClientIdFactory>()
.To<UserIdClientIdFactory>()
.InRequestScope();
//Rest of the other stuff to inject
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
//ninject calls to create the kernal etc
IKernel kernel = CreateKernel();
//TO DO using signal IR resolver
var resolver = new NinjectDependencyResolver(kernel);
SignalR.Hosting.AspNet.AspNetHost.SetResolver(resolver);
}
Enfin, voici le code de mon clientdfactory personnalisé
public class UserIdClientIdFactory : IConnectionIdFactory
{
#region IConnectionIdFactory Members
string IConnectionIdFactory.CreateConnectionId(SignalR.Hosting.IRequest request)
{
// get and return the UserId here, in my app it is stored
// in a custom IIdentity object, but you get the idea
return HttpContext.Current.User.Identity.Name != null ?
//TO DO change to get profileID from Appfabric or the database and log user infor
HttpContext.Current.User.Identity.Name.ToString() :
Guid.NewGuid().ToString();
}
#endregion
}
La solution 2
Ok merci pour votre poteau, m'a fait faire plus de fouilles, j'ai lu le reste du post que vous avez lié à la façon d'utiliser Ninject avec MVC3 qui m'a amené à réaliser que j'avais Ninject mais pas les bits Nuget pour Ninject MVC3, je ajouté cela et alos a modifié mon global.asax en utilisant le post suivant
http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/
Voici le code de travail dans Gloabal.asax J'ai également supprimé le bootstrapper que Ninject MVC3 a ajouté au dossier de démarrage de l'application car c'est ainsi que cela fonctionne dans le post ci-dessus
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.IgnoreRoute("{*allaxd}", new { allaxd = @".*\.axd(/.*)?" }); //added for mango chat
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
public override void Init()
{
this.AuthenticateRequest += new EventHandler(MvcApplication_AuthenticateRequest);
this.PostAuthenticateRequest += new EventHandler(MvcApplication_PostAuthenticateRequest);
base.Init();
}
#region "Ninject stuff for dependancy Injection
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
// kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<UserIdClientIdFactory>()
.To<UserIdClientIdFactory>()
.InRequestScope();
SignalR.Hosting.AspNet.AspNetHost.DependencyResolver.Register(typeof(IConnectionIdFactory), () => new UserIdClientIdFactory());
}
#endregion
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
//for project awesome
ModelMetadataProviders.Current = new AwesomeModelMetadataProvider();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
Autres conseils
En lisant votre question, vous demandez comment effectuer une injection de dépendance appropriée dans ASP.NET MVC et SignalR en utilisant le même conteneur DI (et donc seulement besoin de déclarer les liaisons en un seul endroit). Si cela est correct, j'ai écrit une fois un article de blog à ce sujet: http://lcdev.dk/2012/02/14/using-signalr-ninject-with-asp-net-mvc3-and-the-ninject-mvc3-nuget-package/
Dans le billet de blog, je suppose que vous utilisez ASP.NET MVC3 ainsi que les packages Ninject.Mvc3 et Signalr.Ninject NuGet.
Cependant, si ce n'est pas le cas, j'ai un commentaire sur votre code. Pour moi, il semble que le noyau faisait vos liaisons (en RegisterServices
) n'est pas le noyau que vous vous inscrivez avec Signalr. Et si tel est le cas, alors bien sûr, Signalr ne connaît pas vos liaisons prévues et pourrait lancer une exception à la suite de votre utilisation d'une référence d'objet non inscrite - qui pourrait alors expliquer pourquoi vous ne pouvez plus vous connecter à votre Signalr Hub.