1

我使用 Autofac 作为我选择的 IoC 容器。这个问题的其余部分指的是 SignalR 与 SignalR 的结合,但不需要真正的 SignalR 知识来回答;这是一个源于 Autofac 的问题。

作为使用 Autofac 作为 SignalR 的依赖解析器的一部分,我想提供我自己的 IJsonSerializer 实例,配置我喜欢的方式。但是,我不想让 IJsonSerializer 实例在软件的其余部分中共享。

为此,我使用附加注册创建了一个新的生命周期范围,并将该范围提供给依赖解析器。这是我的问题开始的时候。

我没有意识到的是,通过这样做,以前从根容器中检索到的 SignalR 请求的每生命周期实例依赖项现在正在从生命周期范围请求,因此在整个 SignalR 中共享。不是很好。例如,短期数据库会话现在在我的应用程序的生命周期内共享。

如何使我的每生命周期实例范围依赖项基本上假装我传递给 SignalR 的生命周期范围不应该用于导致这些依赖项被重用?或者,我怎样才能完全避免创建生命周期范围?

4

3 回答 3

1

我最终重写了 SignalR 的 Autofac 集成,以支持为每个 HTTP 上下文创建生命周期范围,方法是依赖 Autofac MVC 支持:

https://github.com/bytenik/Autofac.Integration.Mvc.SignalR

(注意这是 Autofac.Integration.Mvc .SignalR,而不是 Autofac.Integration.SignalR。)

于 2013-02-02T15:16:35.493 回答
1

问题已有几个月了,但我想我会与您分享我使用的方法(也许有人可以改进它)。

我向我的集线器添加了一个事件,在集线器处理后触发。(实际上是通过一个基础集线器,因为无论如何我已经有了一些共同的逻辑)

public event Action OnDisposing;

protected override void Dispose(bool disposing)
{
    if (OnDisposing != null) OnDisposing.Invoke();
}

有了这个,我然后修改了 autofac 注册这个集线器的方式。解析时,会创建一个新的生命周期范围,并在释放集线器时将范围的 dispose 方法设置为触发。

builder.Register(x =>
{
    ILifetimeScope scope = x.Resolve<ILifetimeScope>().BeginLifetimeScope();
    MyHub hub = new MyHub(scope.Resolve<IMyDependency>());
    hub.OnDisposing += scope.Dispose;
    return hub;
})
.As<MyHub>().InstancePerDependency();
于 2013-04-21T11:25:25.410 回答
0

您可以考虑将首选的 IJsonSerializer 实现设置为命名或键控注册,由依赖它的组件专门请求。我对 SignalR 的了解还不够,无法告诉您如何或在哪里可以完成,但它可能会帮助您找到可行的解决方案。

更多详情:http ://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices

于 2013-02-01T17:34:42.607 回答