使用 Autofac 将 SignalR IHubContext 注入控制器

Inject SignalR IHubContext into controller with Autofac

我正在尝试将 SignalR IHubContext 注入 ASP.NET MVC 5 应用程序框架 4.72(不是 .NET Core)中的 Web API 2.x 控制器.它在调用 Web API 控制器时抛出此异常 MyController:

An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor

内部异常说:

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])'.

我不介意使用 属性 注入来完成此操作,但没有任何运气让它起作用。所以我正在注入控制器的c'tor。

我已按照以下答案寻求帮助:

这是 Web API 控制器:

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

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

这里是 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);
    });
}

我错过了什么?谢谢。

您的第一个问题是 typeof(IHubContext)typeof(IHubContext<MyHub>) 不同。您可以使用以下方式解决该问题:

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

但是,旧版本的 SignalR 不能很好地支持通用接口,因此如果您按原样保留比较并注入 IHubContext 而不是 [=14=,它可能会更好] 在 MyController.