我使用Autofac作为我选择的IoC容器。本问题的其余部分将SignalR与SignalR结合起来,但不需要真正的SignalR知识来回答;这是一个植根于Autofac的问题。
作为使用Autofac作为SignalR的依赖解析器的一部分,我想提供我自己喜欢的IJsonSerializer实例。但是,我不希望在整个软件的其余部分共享IJsonSerializer实例。
为了实现这一点,我使用附加注册创建了一个新的生命周期范围,并将该范围提供给依赖项解析器。这是我的问题开始的时候。
我没有意识到,通过执行此操作,现在从生命周期范围请求从SignalR请求的SignalR的每个生命周期范围内的依赖项,因此在整个范围内共享SignalR。这个不好。例如,现在可以在我的应用程序的生命周期内共享短期数据库会话。
如何使我的每个生命周期范围的依赖项基本上假装我传递给SignalR的生命周期范围不应该被用来导致这些依赖项被重用?或者,我怎样才能完全避免创建终身范围?
答案 0 :(得分:1)
我最终重写了SignalR的Autofac集成,以支持为每个HTTP上下文创建一个生命周期范围,依赖于Autofac MVC支持:
https://github.com/bytenik/Autofac.Integration.Mvc.SignalR
(注意这是Autofac.Integration。 Mvc .SignalR,而不是Autofac.Integration.SignalR。)
答案 1 :(得分: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();
答案 2 :(得分:0)
您可以考虑将首选的IJsonSerializer实现设置为命名或密钥注册,以便由依赖它的组件专门请求。我不太了解SignalR告诉你如何或可以在哪里完成,但它可能会帮助你找到一个可行的解决方案。
有关详情:http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices