如何在MVC 5应用程序中配置Autofac和SignalR

时间:2015-11-03 23:30:56

标签: dependency-injection asp.net-mvc-5 signalr autofac signalr-hub

我正在尝试配置MVC 5应用程序以使用SignalR 2.2.x并将服务注入我的NotificationsHub。 我们正在使用Autofac for MVC,但我不确定如何正确配置它。 NuGet Autofac.Integration.SignalR (3.0.2)Autofac.Integration.Mvc (3.3.4)存在Autofac文档。

到目前为止,我正在通过以下方式注册集线器:

ContainerBuilder builder = new ContainerBuilder();

// Register MVC controllers.
builder.RegisterControllers(typeof(MvcApplication).Assembly);

builder.RegisterType<ServiceForSignalRHub>().AsImplementedInterfaces();
builder.RegisterType<...>().AsImplementedInterfaces();

builder.RegisterHubs(Assembly.GetExecutingAssembly());

IContainer container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

然而,对.SetResolver(...)的调用是不确定的,因为它存在于MVC和SignalR集成包中。怎么办?我无法确认我的服务的构造函数注入是否适用于我正在使用的Hub。

修改

我可以使用Autofac配置MVC5就好了。我迷失的地方是如何使用Autofac信号集成NuGet对SignalR做同样的事情。 请参阅下文。

这是我的初创班:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var defaultFactory = LogManager.Use<DefaultFactory>();
        defaultFactory.Directory("@D:\\NServiceBus\\ );
        defaultFactory.Level(LogLevel.Debug);

        var container = ConfigureAutofac(app);

        ConfigureServiceBus(container, app);

        app.UseAutofacMiddleware(container); // REGISTER WITH OWIN
        app.UseAutofacMvc();

        ConfigureAuth(app);

        GlobalConfiguration.Configuration.UseSqlServerStorage("hangfire");

        ConfigureSignalR(app);
    }
}

这是我配置SignalR的部分:

public partial class Startup
{
    public void ConfigureSignalR(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
        builder.RegisterType<MaintenanceService>().As<IMaintenanceService>().PropertiesAutowired();

        var container = builder.Build();
        //var container = new AutofacContainer().Container;

        var resolver = new AutofacDependencyResolver(container);

        // Any connection or hub wire up and configuration should go here
        app.MapSignalR(new HubConfiguration
        {
            Resolver = resolver,
            EnableJSONP = true,
            EnableDetailedErrors = true,
            EnableJavaScriptProxies = true
        });

        builder.RegisterInstance(resolver.Resolve<IConnectionManager>());
    }
}

如何正确完成?

3 个答案:

答案 0 :(得分:2)

您应该在映射时明确告诉SignalR使用AutofacDependencyResolver。 我假设您知道在Startup课程中,您必须致电app.MapSignalR();

在映射它时,应该告诉它使用自定义依赖项解析器(AutofacDependencyResolver)。

我是这样做的:

var resolver = new AutofacDependencyResolver(container);

app.MapSignalR(new HubConfiguration
{
    Resolver = resolver
});

这样,您可以直接告诉SignalR使用哪个依赖性解析器。

我有一个GitHub repo for SignalR Dependency Injection,但它没有配置为使用MVC。不过,我认为它会给你一个如何创建配置的提示。

注意:如果您使用的是OWIN中间件,请确保不要使用GlobalHost静态属性AT ALL,因为它会有很大的不一致性。

  

OWIN集成中的常见错误是使用GlobalHost。在OWIN   您从头开始创建配置。你不应该参考   使用OWIN集成时GlobalHost。

再次,检查我给你的回购,看看如何做到这一点。

希望这会有所帮助:) 祝你好运!

答案 1 :(得分:1)

我最终得到了这个(注意评论):

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);

        IContainer container = AutofacConfig(app);
        app.UseAutofacMiddleware(container);
        app.UseAutofacMvc();
        DependencyResolver.SetResolver(new Autofac.Integration.Mvc.AutofacDependencyResolver(container));
        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        app.UseAutofacWebApi(GlobalConfiguration.Configuration);

        var hubConfiguration = new Microsoft.AspNet.SignalR.HubConfiguration()
        {
            // Resolve presolver from container
            Resolver = container.Resolve<Microsoft.AspNet.SignalR.IDependencyResolver>(),
        };
        app.MapSignalR(hubConfiguration);

        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

_

private static IContainer AutofacConfig(IAppBuilder app)
{
    var builder = new ContainerBuilder();

    RegisterSignalR(builder);

    return builder.Build();
}

_

private static void RegisterSignalR(ContainerBuilder builder)
{
    // Register Autofac resolver into container to be set into HubConfiguration later
    builder.RegisterType<Autofac.Integration.SignalR.AutofacDependencyResolver>()
           .As<Microsoft.AspNet.SignalR.IDependencyResolver>()
           .SingleInstance();

    // Register ConnectionManager as IConnectionManager so that you can get
    // hub context via IConnectionManager injected to your service
    builder.RegisterType<Microsoft.AspNet.SignalR.Infrastructure.ConnectionManager>()
           .As<Microsoft.AspNet.SignalR.Infrastructure.IConnectionManager>()
           .SingleInstance();

    // Register hubs one by one
    builder.RegisterType<MessageNotificationsHub>().ExternallyOwned();
    builder.RegisterType<SystemNotificationsHub>().ExternallyOwned();
}

感谢@Nathan和his answer(最初找到here)和逻辑思维,想要将ConnectionManager注册为IConnectionManager

答案 2 :(得分:0)

安装nuget软件包Autofac.SignalR,例如:

<package id="Autofac.SignalR" version="3.0.2" targetFramework="net471" />

注册您的中心

// during creation of the IContainer, register signalr hubs automatically
var executingAssembly = Assembly.GetExecutingAssembly();
builder.RegisterHubs(executingAssembly);

// alternatively register hubs individually
// ExternallyOwned() ensures SignalR is allowed to control disposal of the hubs rather than Autofac.
builder.RegisterType<NotificationHub>().ExternallyOwned();

设置信号器服务定位器

// replace the Signalr dependency resolver once your IContainer 'container' is ready
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);

// or this can alternatively be set in the HubConfiguration instance when using OWIN IAppBuilder map.RunSignalR(hubConfiguration);
var hubConfiguration = new HubConfiguration
{
    Resolver = new AutofacDependencyResolver(container),
    //...
}

有关更多信息:

https://autofaccn.readthedocs.io/en/latest/integration/signalr.html

https://docs.microsoft.com/en-us/aspnet/signalr/overview/advanced/dependency-injection