我刚开始使用SignalR,并为SignalR创建了一个自定义解析器,因此我可以使用Castle Windsor通过集线器构造器注入依赖项。
我有点假设我只需要注册依赖项,但我发现在我的应用程序工作之前还必须自己注册集线器。这是预期的吗?如果是这样,我应该将哪些生命周期用于集线器?
答案 0 :(得分:7)
默认情况下,SignalR不会使用依赖项解析程序注册每个集线器。相反,它使用IAssemblyLocator
来查找可能包含SignalR Hub的可用程序集。然后IHubDescriptorProvider
搜索Hub的所有可用程序集并创建HubDescriptor
s。
最后,IHubActivator
需要HubDescriptor
并返回一个新实例化的SignalR集线器(使用Activator.CreateInstance
),除非与{{1}相关联的集线器类型已经在依赖项解析器中注册了。在后一种情况下,从HubDescriptor
返回的Hub将直接从依赖项解析器中获取。
通常,SignalR集线器是短暂的,这意味着它们会为每个Hub方法调用创建和销毁。这意味着如果您使用SignalR的依赖项解析程序注册Hub,则应确保每次SignalR解析Hub类型时都返回一个新的Hub实例。
我强烈建议不要注册单身人士中心,原因如下:
可以并行调用Hub方法。发生这种情况时,可以覆盖IHubActivator
作为另一个方法调用的设置的一部分。这可能会导致非常微妙的错误。例如,对于单例集线器,以下代码可能会将除调用者之外的连接添加到组中(这显然可能是一个很大的安全问题):
Hub.Context
[Authorize(Roles="Admin")]
public async Task JoinAdminGroup()
{
await Groups.Add(Context.ConnectionId, "admin");
}
。如果你继续返回相同的Hub,它的Dispose方法将被重复调用。除非您在Hub上实施Dispose,否则这可能不会对您产生影响,因为默认的Dispose实现当前 no-ops。
IIS回收AppDomains。发生这种情况时,无论如何都会被迫重新验证您的Hub。请记住,在您的应用程序在短时间内不可用后,SignalR将自动重新建立活动连接(就像AppDomain回收一样),因此即使您注册,您也可以拥有一个新实例化的Hub来处理预先存在的连接您的Hub作为具有依赖性解析器的Singleton。