自动注入IHubContext SignalR MVC [英] Autofac injection of IHubContext SignalR MVC

查看:112
本文介绍了自动注入IHubContext SignalR MVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让SignalR与Autofac一起使用.我有一份我在这里所做的简写本的回购清单:

I am trying to get SignalR working with Autofac. I have a repo of a stripped back version of what I have done here:

https://github.com/justsayno/signalr-autofac

这是使用 GlobalHost 的作品改编而成的:

This is adapted from which works using GlobalHost:

https://github.com/sstorie/experiments/tree/master/angular2-signalr

使用hte GlobalHost对象可以正常工作.我试图遵循Autofac网站上有关如何注入SignalR服务的文档,但无法使其正常工作.这是我用于注册依赖项的配置文件:

That works just fine using hte GlobalHost object. I have attempted to follow the documentation on Autofac's site about how to inject SignalR services but I cannot get it to work. This is my config file for registering my dependencies:

public static IContainer RegisterDependencies()
    {
        // Create your builder.
        var builder = new ContainerBuilder();

        //register controllers in DI
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // Register SignalR hubs
        builder.RegisterHubs(Assembly.GetExecutingAssembly());

        return builder.Build();
    }

我从startup.cs称呼它:

And I call this from startup.cs:

public class Startup
{
    public static IContainer Container { get; set; }
    public void Configuration(IAppBuilder app)
    {
        var config = GlobalConfiguration.Configuration;

        // configure IoC container
        Container = AutofacConfiguration.RegisterDependencies();

        //set dependency resolver from WebAPI and MVC
        config.DependencyResolver = new AutofacWebApiDependencyResolver(Container);
        DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(Container));

        //register Autofac Middleware
        app.UseAutofacMiddleware(Container);

        app.Map("/signalr", a =>
        {
            a.UseCors(CorsOptions.AllowAll);
            var hubConfiguration = new HubConfiguration
            {
                Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(Container)
            };
            a.RunSignalR(hubConfiguration);
        });

        // This server will be accessed by clients from other domains, so
        //  we open up CORS
        //
        app.UseCors(CorsOptions.AllowAll);

        // Build up the WebAPI middleware
        //
        var httpConfig = new HttpConfiguration();
        httpConfig.MapHttpAttributeRoutes();
        app.UseWebApi(httpConfig);
    }

}

我有一个将其注入到其构造函数中的控制器:

And I have a controller that has this injected into its contstructor:

 public TaskController(IHubContext hubContext)
    {
        // Commented out hard coded global host version
        //
        //_context = GlobalHost.ConnectionManager.GetHubContext<EventHub>();

        // using DI
        _context = hubContext;
    }

但是这给我一个关于控制器没有默认构造函数的错误(因此我认为这是我的IHubContext找不到的问题).

This however gives me an error about the controller not having a default constructor (so I assume this is a problem with my IHubContext not being found).

任何帮助都会很棒.我已经对我正在谈论的内容进行了回购,可以在此处找到完整的解决方案:

Any help would be great. I have made a repo of what I am talking about that can be found here for a complete solution:

https://github.com/justsayno/signalr-autofac

推荐答案

我已经能够做到这一点,但是它并不像我通常想要的那么干净.这里的主要问题是IHubContext不能反映它是哪种特定的集线器类型……它只是一个通用句柄.因此,我要做的是在Autofac中创建一个命名注册,以使用特定的SignalR集线器注册IHubContext:

I've been able to do this, but it's not as clean as I would normally like. The primary issue here is that IHubContext does not reflect what specific type of hub it is...it's just a generic handle. So what I've done is to create a named registration within Autofac to register IHubContext using a specific SignalR hub:

builder.Register(ctx => 
    ctx.Resolve<IDependencyResolver>()
       .Resolve<IConnectionManager>()
       .GetHubContext<EventHub>())
       .Named<IHubContext>("EventHub");

然后,我为将要插入此中心的对象设置特定的注册.这可以是ApiController,也可以是其他一些服务,然后使用标准的Autofac/WebApi集成将其注入到控制器中.这种特定的"注册是我不喜欢的,但是我不知道有一种更干净的解决方法.如下所示:

Then I set up specific registrations for the objects I'll be injecting this hub into. This could be either an ApiController, or perhaps some other service that is then injected into controllers using the standard Autofac/WebApi integration. This "specific" registration is the piece I don't like, but I don't know of a cleaner way around it. Here's what that would look like:

builder.RegisterType<TaskController>()
       .WithParameter(
           new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(IHubContext),
               (pi, ctx) => ctx.ResolveNamed<IHubContext>("EventHub")
       )
 );

现在,Autofac应该会认识到您要将IHubContext注入到 TaskController 中,并在注入时提供名为 EventHub 的特定注册.

Now Autofac should recognize that you want to inject IHubContext into the TaskController and provide the specific registration named EventHub when injecting it.

这篇关于自动注入IHubContext SignalR MVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆