Вставить Structuremap в SignalR на самом деле довольно просто.Сначала вы хотите создать свой собственный преобразователь:
StructureMap Resolver
Использование:
using SignalR.Infrastructure;
using StructureMap;
Класс:
public class StructureMapResolver : DefaultDependencyResolver
{
private IContainer _container;
public StructureMapResolver(IContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
object service = null;
if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
{
// Concrete type resolution
service = _container.GetInstance(serviceType);
}
else
{
// Other type resolution with base fallback
service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
}
return service;
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = _container.GetAllInstances(serviceType).Cast<object>();
return objects.Concat(base.GetServices(serviceType));
}
}
Идея состоит в том, чтобы попытаться использовать ваш контейнер для разрешения зависимостей. Если у вас нет подключенной зависимости, передайте ее преобразователю по умолчанию.Таким образом, вам не нужно беспокоиться обо всех других зависимостях в SignalR, и вы можете сосредоточиться только на том, что вы хотите внедрить (Hubs, ConnectionIdFactory, MessageBus и т. Д.).
Привязки для Resolver иКонцентратор
Далее вы захотите зарегистрировать это в своем контейнере (мне нравится использовать реестры):
Использование:
using SignalR.Infrastructure;
using StructureMap.Configuration.DSL;
Класс:
public class ExtensionsRegistry : Registry
{
public ExtensionsRegistry()
{
For<IDependencyResolver>().Add<StructureMapResolver>();
}
}
Замена резольвера
Наконец, вы захотите указать SignalR использовать ваш резольвер вместо значения по умолчанию:
Global ::Application_Start или WebActivator :: Pre_Start
Использование:
using SignalR.Hosting.AspNet;
using SignalR.Infrastructure;
Application_Start:
// Make sure you build up the container first
AspNetHost.SetResolver(StructureMap.ObjectFactory.GetInstance<IDependencyResolver>());
SillyКонцентратор с внедренными зависимостями
Теперь вы можете просто вставить любые зависимости, о которых знает ваш контейнер, в сами концентраторы:
[HubName("defaultHub")]
public class DefaultHub : Hub, IDisconnect
{
private readonly IRepository _repo;
public DefaultHub(IRepository repo)
{
_repo = repo;
}
public void Connect()
{
Caller.setUser(Context.ConnectionId);
Clients.addMessage(string.Format("{0} has connected", Context.ConnectionId));
}
public void MessageSender(string message)
{
Caller.addMessage(_repo.RepositoryMessage());
Clients.addMessage(message);
}
public Task Disconnect()
{
var clientId = this.Context.ConnectionId;
return Task.Factory.StartNew(() => { Clients.addMessage(string.Format("{0} has disconnected", clientId)); });
}
}