Autofac难题

时间:2013-02-01 17:29:43

标签: c# autofac lifetime-scoping

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

作为使用Autofac作为SignalR的依赖解析器的一部分,我想提供我自己喜欢的IJsonSerializer实例。但是,我不希望在整个软件的其余部分共享IJsonSerializer实例。

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

我没有意识到,通过执行此操作,现在从生命周期范围请求从SignalR请求的SignalR的每个生命周期范围内的依赖项,因此在整个范围内共享SignalR。这个不好。例如,现在可以在我的应用程序的生命周期内共享短期数据库会话。

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

3 个答案:

答案 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