NancyFx - 如何释放在应用程序容器中注册为单一实例的实例

本文关键字:实例 注册 单一 应用程序 何释放 释放 NancyFx | 更新日期: 2023-09-27 18:35:13

我的特定上下文是一个自托管的Nancy应用程序,我正在使用RavenDb嵌入式文档数据库。

我的引导程序如下所示:

public class MyBootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);
        container.Register<IDocumentStore>(CreateDefaultStore());
        container.Register<IDoSomething, MyOtherType>().AsSingleton(); // implements IDisposable
    }
    private static IDocumentStore CreateDefaultStore(){...}
}

问题是我期望在 NanyHost 停止时调用 IDocumentStore 和我的自定义一次性类型的 Dispose 方法。

NancyHost 实现了 IDisposable,

TinyIoCContainer 实现了 IDisposable,如果我在请求容器中注册了一个实现 IDisposable 的类型,它将被释放。我几乎可以肯定,当主机被释放时,容器将被释放,所有注册的实例都将被释放。

我知道我可以在引导程序外部存储对文档存储的引用,并在主机停止后释放它,我还可以想到一些其他技巧,例如让引导程序实现 IDisposable 并在主机停止后手动处置它,但我跳跃有一种更自动的方式来处理所有注册实例的处置。

我是否缺少一些在应用程序容器中注册的单例实例上调用 Dispose() 的聪明方法?

我的猜测是,由于主机和应用程序容器预计会一直存在到应用程序结束,因此处置容器不是优先事项,但是,如果是这种情况,这似乎是一种不好的做法。

更新:发布后,我在 nancy 组上找到了这个线程,其中包含一些与此相关的信息,但有点旧。

NancyFx - 如何释放在应用程序容器中注册为单一实例的实例

尽管应用关闭不需要这样做,但在自承载和 OWIN 方案中,你可能希望"重启"服务器组件,而不拆除 AppDomain - 在这些情况下,对最终确定性更强显然是有益的。

为此,我将引导程序

更改为可处置,使我们的引导程序基类释放应用程序容器(如果它实现了 IDisposable),并连接主机以在释放主机时将其全部释放:

https://github.com/NancyFx/Nancy/pull/1268

读取您提供的源代码时,RavenDb 并未完全实现 IDIsposable 模式。根据最佳实践,实现 IDisposable 的类应具有终结器,用于清理非托管资源。在这种情况下,GC将执行任何需要的操作。

在你提供的 RavenDb 代码中,Dispose 方法不处理任何非托管资源,因此如果未调用它,则不应有任何泄漏。当然,这假设EmbeddableDocumentStore引用的托管资源具有"适当的"ID是可操作的模式,如果它们持有非托管资源(我没有检查)。

如果您仍有顾虑,可以:

  1. 针对 RavenDB 提交错误请求,以便他们修复
  2. 在 DocumentStore 周围使用包装器,它可以正确实现 IDisposable 模式。

无论如何,我不认为"在.Net框架上中继以完成它的工作"是一件坏事,除非存在经过验证的错误/需求。假设应用程序容器存在于应用程序的整个生命周期中,当应用程序终止时,GC 将负责适当的处置。