4 votes

Injecter SignalR IHubContext dans le contrôleur avec Autofac

J'essaie d'injecter un SignalR IHubContext dans un contrôleur Web API 2.x dans une application ASP.NET MVC 5 Framework 4.72 (pas .NET Core). Il lance cette exception lors de l'appel au contrôleur de l'API Web MyController :

Une erreur s'est produite lors de la création d'un contrôleur de type "MyController". Assurez-vous que le contrôleur possède un constructeur public sans paramètre.

L'exception intérieure dit :

Aucun des constructeurs trouvés avec 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' sur le type 'MyController' ne peut être invoqué avec les services et paramètres disponibles : Impossible de résoudre le paramètre "Microsoft.AspNet.SignalR.IHubContext". [MyHub] context' of constructor 'Void .ctor(Microsoft.AspNet.SignalR.IHubContext [MyHub])".

Cela ne me dérange pas d'utiliser l'injection de propriétés, mais je n'ai pas réussi à faire fonctionner cette méthode. Je fais donc de l'injection dans le c'tor du contrôleur.

J'ai suivi ces réponses pour obtenir de l'aide :

Voici le contrôleur de l'API Web :

public class MyController : WebApiController
{
    public IHubContext<MyHub> Context { get; set; }

    public MyController(IHubContext<MyHub> context)
    {
        Context = context;
    }   
}

Et voici la partie pertinente de l'article Startup.cs :

public void Configuration(IAppBuilder app)
{
    // Other code...

    var builder = new ContainerBuilder();
    var config = new HttpConfiguration();

    builder.RegisterHubs(Assembly.GetExecutingAssembly());
    builder.RegisterControllers(typeof(MvcApplication).Assembly)
        .InstancePerRequest();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
        .InstancePerRequest();
    builder.RegisterType<AutofacDependencyResolver>()
        .As<IDependencyResolver>()
        .SingleInstance();

    builder
        .Register(c => c.Resolve<IConnectionManager>().GetHubContext<MyHub>())
        .Named<IHubContext>("MyHub");
    builder.RegisterType<MyController>()
        .WithParameter(
            new ResolvedParameter(
                (pi, ctx) => pi.ParameterType == typeof(IHubContext),
                (pi, ctx) => ctx.ResolveNamed<IHubContext>("MyHub")
            )
        );

    var container = builder.Build();
    app.UseAutofacMiddleware(container);

    DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
    config.DependencyResolver = new AutofacWebApiDependencyResolver((IContainer)container);

    app.Map("/signalr", map =>
    {
        var hubConfiguration = new HubConfiguration
        {
            Resolver = new AutofacDependencyResolver(container),
        };

        map.RunSignalR(hubConfiguration);
    });
}

Qu'est-ce que je manque ? Merci d'avance.

2voto

BradleyDotNET Points 12000

Votre premier problème est que typeof(IHubContext) n'est pas la même chose que typeof(IHubContext<MyHub>) . Vous pouvez contourner ce problème en utilisant :

pi.ParameterType == typeof(IHubContext).MakeGenericType(typeof(MyHub))

Cependant, les anciennes versions de SignalR ne supportent pas très bien les interfaces génériques. Il serait donc préférable de laisser la comparaison telle quelle et d'injecter un élément de type IHubContext plutôt qu'un IHubContext<MyHub> en MyController .

-2voto

develomer Points 41

Pouvez-vous essayer de l'ajouter ?

app.UseSignalR(routes =>
{
   routes.MapHub<MyHub>("/MyHub");
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X