Использование существующего контейнера IoC в SignalR 2.0

Как я могу использовать существующий IoC с SignalR 2.0?

Из учебника кажется, что мне нужно настроить класс для вызова из OWIN через атрибут:

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app /*HOW AM I GONNA GET UNITY CONTAINER HERE?*/) 
        {
            var hubConfig = new HubConfiguration()
            {
                EnableJSONP = true,
                EnableDetailedErrors = true,
                EnableJavaScriptProxies = true,
                Resolver = new SignalRUnityDependencyResolver(container)  
            };


            // Any connection or hub wire up and configuration should go here
            app.MapSignalR(hubConfig);
        }
    }
}

Проблема здесь в том, что у меня уже есть контейнер, он загружен, и в контейнере есть единичные экземпляры, которые необходимо использовать совместно с приложением MVC, совместно используемым на том же хосте.

Однако проблема в том, что, в отличие от ранее, я не могу назвать MapSignalR метод из моего собственного кода. Скорее мне нужно положиться на OWIN, чтобы сделать это для меня. Однако OWIN не знает о контейнере, который я уже настроил.

Какой лучший способ решить эту проблему? У меня есть несколько очень грубых идей, как собрать решение вместе, используя статические переменные для хранения некоторых из них - но я ненавижу саму мысль об этом. Код будет хрупким, и порядок работы может легко привести к незначительной ошибке.

Есть ли способ получить экземпляр IAppBuilder, не вызывая OWIN вышеупомянутый метод? Таким образом, я могу лучше контролировать, когда SignalR инициализируется, и я могу передать свой собственный IoC в конфигурацию.

1 ответ

В моем случае я создал собственный активатор-концентратор, который использует общий контейнер между моим приложением и signalR (путем внедрения в конструктор), так что у вас будет единый составной корень для всего приложения.

попробуйте следующее:

public class CustomHubActivator : IHubActivator
    {
        private readonly Container _container;

        public MseHubActivator(Container container)
        {
            _container = container;
        }

        public IHub Create(HubDescriptor descriptor)
        {
            return _container.GetInstance(descriptor.HubType) as IHub;
        }
    }

зарегистрируйте свой собственный активатор концентратора, когда вы загружаете свое приложение (возможно, global.asax)

 GlobalHost.DependencyResolver.Register(typeof (IHubActivator),
                                                   () => new CustomHubActivator(Container));

это гораздо более простое решение, чем повторная настройка signalR dependencyResolver

Другие вопросы по тегам