【发布时间】:2015-04-18 01:21:57
【问题描述】:
我们有几个托管在 Windows 服务中的应用程序,这些应用程序自托管一个 Nancy 端点,以便公开有关应用程序操作的检测。
我们使用 Autofac 作为我们的 IOC。几个存储库注册到所有应用程序共享的核心 DLL 中的根容器中;然后使用从Nancy.Autofac.Bootstrapper 派生的引导程序将此容器作为其容器传递给 Nancy。
我们发现,当 Nancy 收到一个 Web 请求时,它会解析来自根容器的存储库请求,这导致内存被非垃圾收集 IDisposables 消耗,因为根容器不去超出范围(它具有 Windows 服务的生命周期)。这导致服务“泄漏”内存。
然后我们切换到一个模型,在该模型中,我们使用 Nancy 引导程序中覆盖的 ConfigureRequestContainer() 方法中的 InstancePerRequest 添加存储库注册:
protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
{
base.ConfigureRequestContainer(container, context);
PerRequestContainerBuilder().Update(container.ComponentRegistry);
}
private static ContainerBuilder PerRequestContainerBuilder()
{
var builder = new ContainerBuilder();
// Dependency for repository
builder.RegisterType<SystemDateTimeProvider>().InstancePerRequest().As<IDateTimeProvider>();
// Repository
builder.RegisterType<BookmarkRepository>().InstancePerRequest().As<IBookmarkRepository>();
return builder;
}
我们还重写了CreateRequestContainer() 方法来创建带有标签MatchingScopeLifetimeTags.RequestLifetimeScopeTag 的请求容器。
protected override ILifetimeScope CreateRequestContainer(NancyContext context)
{
return ApplicationContainer.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
}
这似乎解决了IDisposables 没有被释放的问题 - 子请求容器在 Web 请求管道的末端被释放,由它解析的对象也被释放并最终被垃圾回收。
我们的问题是,这似乎将存储库的实现细节泄漏到服务中,因为我们不仅要在ConfigureRequestContainer() 中注册存储库,还要注册存储库所需的任何其他对象,即如果我们想要更改存储库的实现,我们必须“遍历依赖链”以在每个使用它的服务中注册所需的对象 - 这似乎是错误的。
有没有一种方法可以让 Autofac 从根容器中解析存储库的支持对象,但将注册信息保留在 Web 请求容器的范围内?或者有没有办法在创建时自动将现有注册从根容器复制到子容器中?
【问题讨论】:
-
我不确定您所说的“如果我们想更改存储库的实现,我们必须“遍历依赖链”以在每个使用它的服务中注册所需的对象”是什么意思?顺便说一句,从 Nancy 1.1 开始,不需要覆盖
CreateRequestContainer来添加请求生命周期标签。它是默认完成的。见github.com/NancyFx/Nancy.Bootstrappers.Autofac/pull/24
标签: c# dependency-injection autofac nancy