Использование существующего контейнера 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