根据this的帖子,应该可以将每个Web请求的依赖关系注入到SignalR集线器中(虽然有一些限制,例如OnDisconnected()方法的问题)。在我的情况下,它是ASP Web API(不是MVC),并且由于某种原因它不起作用。SignalR集线器中简单的喷油器对web-api-request的依赖关系
以下是有关部分:
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.
这是预期的,据我所知。但是我得到完全相同的异常,当我改变仓库的生活方式瞬态:
var transientHybrid = Lifestyle.CreateHybrid(() => HttpContext.Current != null, new WebApiRequestLifestyle(), Lifestyle.Transient);
container.Register<ISampleRepository, SampleRepository>(transientHybrid);
我怀疑问题可能在于HttpContext.Current != null
检查不工作的Web API的方式为MVC相同。
SignalR 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
一个集线器,但这个范围必须明确地关闭它使事情变得更加复杂......
非常感谢您的回答@Steven。当你说“并确保这样一个执行上下文范围是在你的集线器解决之前启动的。”你的意思是使用container.BeginExecutionContextScope()?由于这个范围需要被明确处理,如果没有使用CommandHandler模式,你会如何建议实现这个部分。也应该被Hubs注册为WebApiRequest Lifestyles?谢谢! –
@IljaS。我无法真正回答这个问题。我不知道你的实现是怎么样的,在什么时候你得到这个堆栈跟踪(以及我的SignalR经验缺乏)。尝试使用更多的代码和完整的堆栈跟踪来更新您的问题我会看一看。 – Steven
实际上并没有太多的实施。为了简单起见,我们可以说它是非常简单的WebApi应用程序,带有1个注入了DbContext的Repository类。 1 Hub,我想注入这个Repository类。那就是它。我添加了SignalR调用Hub创建的Stack trace。我不知道还有什么要包括的。 –