【问题标题】:How do I ensure that NInject2 disposes of objects in the correct order?如何确保 NInject2 以正确的顺序处理对象?
【发布时间】:2012-01-24 06:05:59
【问题描述】:

具体来说,如果我使用 NInject 创建一堆已绑定在单例范围内的对象,我希望 NInject 以相反的顺序释放它们。

我有一个测试用例如下,我想知道是我做错了什么,还是NInject2有bug。

我希望看到这一点,鉴于我已经创建了一个 Foo 的实例,然后是一个 Bar 的实例,NInject 应该在释放 Foo 之前释放 Bar!为什么不这样做?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;

namespace ConsoleApplication1
{
    interface IFoo
    {
    }

    interface IBar
    {
    }

    class Foo : IFoo, IDisposable
    {
        public Foo()
        {
            System.Console.WriteLine("Created Foo Instance");
        }
        public void Dispose()
        {
            System.Console.WriteLine("Disposed Foo Instance");
        }
    }

    class Bar : IBar, IDisposable
    {
        public Bar(IFoo foo)
        {
            System.Console.WriteLine("Created Bar Instance");
        }
        public void Dispose()
        {
            System.Console.WriteLine("Disposed Bar Instance");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var kernel = new Ninject.StandardKernel())
            {
                kernel.Bind<IBar>().To<Bar>().InSingletonScope();
                kernel.Bind<IFoo>().To<Foo>().InSingletonScope();

                kernel.Get<IFoo>();
                kernel.Get<IBar>();
            }
        }
    }
}

实际输出:

Created Foo Instance
Created Bar Instance
Disposed Foo Instance
Disposed Bar Instance

预期输出:

Created Foo Instance
Created Bar Instance
Disposed Bar Instance
Disposed Foo Instance

【问题讨论】:

  • (顺便说一下,我使用的是 .NET 4.0 的“无网络”版本,因此我可以在 .NET 4.0 客户端配置文件上使用 NInject)

标签: ninject ninject-2


【解决方案1】:

Ninject 目前没有引用计数。因此,这些实例以任何顺序排列。如果你想要这个,你必须编写一个具有引用计数的 ICache 实现。

或者,您可以使用命名范围定义 Foo 在 Bar 的范围内。这将确保 Foo 不会在 Bar 之前被释放。

【讨论】:

  • 您不需要引用计数来执行此操作 - 您所要做的就是将每个创建的项目附加到列表中......然后以相反的顺序处理它们。引用计数会增加比它解决的问题更多的问题。也就是说,看看github.com/ninject/ninject/blob/master/src/Ninject/Activation/…,这对我来说似乎很容易实现,我应该如何用我自己的 NInject 实现来代替?
  • 现在,我已经停止使用 .InSingletonScope(),现在明确地将我使用的几个真正的单例重新绑定到常量,因为我无法在 Bar 的范围内定义 Foo。如果我使用这样的范围,我会错过 NInject 以声明方式定义依赖项的能力。 (我使用基于约定的绑定)
  • 这一切实际上都完美地回答了这个问题,看起来我应该能够(相当优雅地)在工作中实现它,谢谢!
  • 不幸的是,如果您想以相反的顺序进行处理,则涉及更多内容,因此仅使用列表是行不通的。例如。并非所有对象都在单例范围内。还有其他寿命较短的范围。
  • 嗯,这会使事情复杂化。现在我想到了,我认为您正在尝试解决一个更复杂的情况,即 NInject 在整个项目中用作服务定位器,而不仅仅是作为 Program.cs 中的自动装配手段。我认为对我来说,使用反向列表会起作用——我只有一个范围,它引入了正确的语义。通常情况下,我会对 transcient 范围感到满意,除了在这种情况下 'Foo' 和 'Bar' 是 C++ 对象,我需要以可预测的方式处理它们。是否有任何文档讨论 NInject 项目中的所有权语义?
猜你喜欢
  • 1970-01-01
  • 2015-05-26
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多