简体   繁体   English

使用 Autofac 将 SignalR IHubContext 注入 controller

[英]Inject SignalR IHubContext into controller with Autofac

I'm trying to inject a SignalR IHubContext into a Web API 2.x controller in an ASP.NET MVC 5 app Framework 4.72 (not .NET Core).我正在尝试将 SignalR IHubContext注入到 Web API 2.x controller ASP.NET MVC 5 app Framework 4.72(不是 .NET Core)中。 It's throwing this exception when calling the Web API controller MyController :调用 Web API controller MyController时抛出此异常:

An error occurred when trying to create a controller of type 'MyController'.尝试创建“MyController”类型的 controller 时出错。 Make sure that the controller has a parameterless public constructor确保 controller 具有无参数公共构造函数

The inner exception says:内部异常说:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyController' can be invoked with the available services and parameters: Cannot resolve parameter 'Microsoft.AspNet.SignalR.IHubContext [MyHub] context' of constructor 'Void.ctor(Microsoft.AspNet.SignalR.IHubContext [MyHub])'.无法使用可用服务和参数调用类型为“MyController”的“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”中的构造函数:无法解析[MyHub] context' of constructor 'Void.ctor(Microsoft.AspNet.SignalR.IHubContext [MyHub])'。

I don't mind doing this using property injection but haven't had any luck getting that to work.我不介意使用属性注入来做到这一点,但没有任何运气让它发挥作用。 So I'm doing injection into the c'tor of the controller.所以我正在注入 controller 的 c'tor。

I've followed these answers for help:我已经按照这些答案寻求帮助:

Here's the Web API controller:这是 Web API controller:

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

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

And here's the pertinent part of the Startup.cs :这是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);
    });
}

What am I missing?我错过了什么? Thanks.谢谢。

Your first problem is that typeof(IHubContext) is not the same as typeof(IHubContext<MyHub>) .您的第一个问题是typeof(IHubContext)typeof(IHubContext<MyHub>) You can get around that by using:你可以通过使用来解决这个问题:

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

However, old versions of SignalR don't support the generic interfaces very well, so it would probably work better if you left the comparison as is, and inject an IHubContext rather than an IHubContext<MyHub> in MyController .但是,SignalR 的旧版本不能很好地支持通用接口,因此如果您按原样保留比较并在MyController中注入IHubContext而不是IHubContext<MyHub>可能会更好。

I'm trying to inject a SignalR IHubContext into a Web API 2.x controller in an ASP.NET MVC 5 app Framework 4.72 (not .NET Core). I'm trying to inject a SignalR IHubContext into a Web API 2.x controller in an ASP.NET MVC 5 app Framework 4.72 (not .NET Core). It's throwing this exception when calling the Web API controller MyController :调用 Web API controller MyController时抛出此异常:

An error occurred when trying to create a controller of type 'MyController'.尝试创建类型为“MyController”的 controller 时发生错误。 Make sure that the controller has a parameterless public constructor确保 controller 有一个无参数的公共构造函数

The inner exception says:内部异常说:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyController' can be invoked with the available services and parameters: Cannot resolve parameter 'Microsoft.AspNet.SignalR.IHubContext [MyHub] context' of constructor 'Void.ctor(Microsoft.AspNet.SignalR.IHubContext [MyHub])'.无法使用可用的服务和参数调用在类型“MyController”上使用“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到的任何构造函数:无法解析[MyHub] context' of constructor 'Void.ctor(Microsoft.AspNet.SignalR.IHubContext [MyHub])'。

I don't mind doing this using property injection but haven't had any luck getting that to work.我不介意使用属性注入来做到这一点,但没有任何运气让它发挥作用。 So I'm doing injection into the c'tor of the controller.所以我正在注入 controller 的 c'tor。

I've followed these answers for help:我已按照以下答案寻求帮助:

Here's the Web API controller:这是 Web API controller:

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

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

And here's the pertinent part of the Startup.cs :这是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);
    });
}

What am I missing?我错过了什么? Thanks.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM