带有IoC的SignalR(Castle Windsor) - 集线器的寿命是多少?

时间:2014-01-14 10:39:00

标签: inversion-of-control castle-windsor signalr signalr-hub

我刚开始使用SignalR,并为SignalR创建了一个自定义解析器,因此我可以使用Castle Windsor通过集线器构造器注入依赖项。

我有点假设我只需要注册依赖项,但我发现在我的应用程序工作之前还必须自己注册集线器。这是预期的吗?如果是这样,我应该将哪些生命周期用于集线器?

1 个答案:

答案 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实例。

我强烈建议不要注册单身人士中心,原因如下:

  1. 可以并行调用Hub方法。发生这种情况时,可以覆盖IHubActivator作为另一个方法调用的设置的一部分。这可能会导致非常微妙的错误。例如,对于单例集线器,以下代码可能会将除调用者之外的连接添加到组中(这显然可能是一个很大的安全问题):

    Hub.Context
  2. 每次激活后都会调用
  3. [Authorize(Roles="Admin")] public async Task JoinAdminGroup() { await Groups.Add(Context.ConnectionId, "admin"); } 。如果你继续返回相同的Hub,它的Dispose方法将被重复调用。除非您在Hub上实施Dispose,否则这可能不会对您产生影响,因为默认的Dispose实现当前 no-ops。

  4. IIS回收AppDomains。发生这种情况时,无论如何都会被迫重新验证您的Hub。请记住,在您的应用程序在短时间内不可用后,SignalR将自动重新建立活动连接(就像AppDomain回收一样),因此即使您注册,您也可以拥有一个新实例化的Hub来处理预先存在的连接您的Hub作为具有依赖性解析器的Singleton。

  5. https://github.com/SignalR/SignalR/blob/2.0.1/src/Microsoft.AspNet.SignalR.Core/DefaultDependencyResolver.cs#L79