1

我想配置一個MVC 5應用程序以使用SignalR 2.2.x並將服務注入到我的NotificationsHub中。 我們使用Autofac for MVC,但我不確定如何正確配置它。 Autofac文檔存在NuGet Autofac.Integration.SignalR(3.0.2)和Autofac.Integration.Mvc(3.3.4)。如何在MVC 5應用程序中配置Autofac和SignalR

我在做什麼,到目前爲止是通過註冊中心:

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(...)是ambigious,因爲它在這兩個MVC和SignalR集成軟件包存在。怎麼辦?我無法確認我的服務的構造器注入是否適用於我正在使用的Hub。

編輯

我可以Autofac就好配置MVC5。我迷失的地方是如何使用Autofac Signal集成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>()); 
    } 
} 

怎麼可以這樣做正確?

回答

2

當您映射SignalR時,您應該明確告訴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中間件,請確保不要使用AT ALL的GlobalHost靜態屬性,因爲它會有很大的不一致性。

A common error in OWIN integration is use of the GlobalHost. In OWIN you create the configuration from scratch. You should not reference GlobalHost anywhere when using the OWIN integration.

再次,檢查我給你的回購看看如何做到這一點。

希望這會有所幫助:) 祝你好運!

+0

感謝您的好回答。我沒有得到它在我的最終工作。由於我使用MVC5,我的項目設置稍有不同。我確實使用OWIN。有一件事:我抓住你的回購,並做了一個軟件包更新,以匹配我使用的版本號。現在演示不會運行。 – John

+0

是的,這是因爲使用Redis的SignalR背板。從中刪除所有與Redis相關的事物。我會盡快提交更改,但在此之前,請刪除關於Redis的所有內容:啓動時的app.UseRedis和Microsoft.AspNet.SignalR.Redis NuGet包。它會工作:)詢問是否有任何問題,我會盡力更新它:)祝你好運! –

+0

謝謝你做到了。我仍然不確定如何配置MVC Autofac和SignalR Autofac,但接下來的問題是我得到了一個SignalR JS錯誤:「SignalR:Connection尚未完全初始化,請使用.start()。done()或.start ().fail()在連接啓動後運行邏輯。「有什麼建議?再次感謝! – John

0

我結束了這個(注意註釋):

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註冊爲ICon的邏輯思維nectionManager

相關問題