根据this发布后,应该可以将每个网络请求的依赖项注入 SignalR 集线器(尽管有一些限制,例如 OnDisconnected() 方法的问题)。就我而言,它是 ASP Web API(不是 MVC),但由于某种原因它不起作用。
以下是相关部分:
container.RegisterWebApiControllers(httpConfiguration);
container.RegisterWebApiRequest<DbContext, MyDbContext>();
container.RegisterWebApiRequest<ISampleRepository, SampleRepository>(); //DbContext injected to SampleRepository
//Enable injections to SignalR Hubs
var activator = new SimpleInjectorHubActivator(container);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);
这个类可以注入集线器:
public class SimpleInjectorHubActivator : IHubActivator
{
private readonly Container _container;
public SimpleInjectorHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.GetInstance(descriptor.HubType);
}
}
和集线器本身:
[HubName("sample")]
public class SampleHub : Hub
{
public ActiveBetsHub(ISampleRepository repository)
{
}
//Irrelevant methods here. OnDisconnected() NOT implemented!
}
通过这种设置,我得到了异常:
No registration for type SampleHub could be found and
an implicit registration could not be made.
The ISampleRepository is registered as 'Web API Request'
lifestyle, but the instance is requested outside the context of a Web API Request.
据我了解,这是预期的。但是,当我将存储库的 Lifestyle 更改为 Transient 时,我得到了完全相同的异常:
var transientHybrid = Lifestyle.CreateHybrid(() => HttpContext.Current != null, new WebApiRequestLifestyle(), Lifestyle.Transient);
container.Register<ISampleRepository, SampleRepository>(transientHybrid);
我怀疑问题可能出在HttpContext.Current != null
检查它是否适用于 Web API,就像适用于 MVC 一样。
信号R 2.2
简单注入器2.8.3
我想念什么?
UPDATE:
这是 SignalR 如何创建集线器的堆栈跟踪:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance(Type serviceType)
at MyWebAbi.WebApiApplication.SimpleInjectorHubActivator.Create(HubDescriptor descriptor) in Global.asax.cs:line 108
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, StateChangeTracker tracker, Boolean throwIfFailedToCreate)
所以正确的解决方案是使用ExecutionContextScope
对于集线器,但需要明确关闭此范围,这使事情变得更加复杂......