1

Я пытаюсь настроить приложение MVC 5 на использование SignalR 2.2.x и внедрить службу в мой NotificationsHub. Мы используем Autofac для MVC, но я не уверен, как правильно его настроить. Документация Autofac существует для NuGet Autofac.Integration.SignalR (3.0.2) и Autofac.Integration.Mvc (3.3.4).Как настроить Autofac и SignalR в приложении MVC 5

Что я делаю до сих пор регистрируют концентраторов с помощью:

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 пакетов интеграции. Что теперь? Я не могу подтвердить, работает ли контрструктура моего сервиса для концентратора, который я использую.

EDIT

Я могу настроить MVC5 с Autofac просто отлично. Где я заблудился, как сделать то же самое с SignalR, используя интеграцию сигналов Autofac Signal NuGet. См. Ниже.

Это мой класс запуска:

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 явно использовать 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, так как оно будет иметь значительные несоответствия.

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

Да, это из-за объединительной платы SignalR, которая использует Redis. Удалите из него все связанные с Редисом вещи. Я зафиксирую изменения, как только у меня появится окно, но до этого удалите все, что вы найдете о Redis: app.UseRedis из Startup и пакета 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(); 
    } 

Благодаря и his answer @ Натан (первоначально найден here) и логическое мышление, чтобы выяснить, зарегистрировать ConnectionManager как ICon nectionManager

Смежные вопросы