Ninject 3如何影响对象的生命周期?

时间:2013-04-13 01:49:33

标签: c# ninject

在我用Ninject重构我的DI项目之前,我有一个简单的测试类和一个简单的方法:

    public void TestImport()
    {
        var functionality = new ImportFunctionality();
        functionality.Execute();
    }

当我运行这个“应用程序”(只是一个用于集成测试我的库的沙箱WPF客户端应用程序)时,我显示了“主”窗口并单击该窗口上的一个名为TestImport方法的按钮,执行然后我可以测试和调试我的代码,当主窗口关闭时,应用程序就在那里死了,VS将退出调试模式。正常的东西。

然后我重构了整个事情,并在整个代码中使用Ninject,工厂和接口实现了依赖注入; TestImport方法现在看起来像这样:

    public void TestImport()
    {
        using (var kernel = new StandardKernel())
        {
            kernel.Load<SecurityNinjectModule>();
            kernel.Load<HelpersNinjectModule>();
            kernel.Load<ImportFunctionalityNinjectModule>();

            var functionality = kernel.Get<IImportFunctionality>();
            functionality.Execute();
        }
    }

现在,当我运行WPF沙箱/测试应用程序时,一切正常,这很好,除非“主”窗口关闭,应用程序不再退出,Visual Studio仍处于调试模式 。我将呼叫添加到Dispose()以希望修复它,但没有运气;将它包装在using块中也不会解决它。

如果我运行沙箱而不点击按钮运行TestImport方法,然后关闭主窗口,应用程序将正常关闭。

这引导我进入Ninject内核对象。尽管有Dispose()电话,它能以某种方式保留其资源吗?那么如何正确关闭运行Ninject 3.0的应用程序?

修改 如果我打开debug / windows / threads窗口,我会看到所有实例化的线程都处于休眠或“处于休眠,等待或加入”状态,如果不是“不可用”;一个名为.NET System Events的线程正在睡觉,等待或加入;主线程是“管理到本机转换”以及一个名为vshost.RunParkingWindow的线程 - 这是我到达Why won't my WPF application close properly after it displays a WinForms dialog?的地方。答案似乎是有效的,因为它被接受,但正如@BahriGungor所说“使用System.Environment.Exit就像使用炸药来制作一扇门,因为你不想按照出口标志 ”。它并没有说为什么会发生这种情况

有趣的是,它不会始终如一地发生:有时我可以打破并逐步执行代码,当我“F5”恢复,然后关闭主窗口时,它会正常关闭。发生了什么事?

编辑2 该功能会显示FileDialog,如果该对话框未返回Excel工作簿的文件名,则导入窗口不会显示。我把它缩小到了这个范围:

  • 如果显示导入视图,无论关闭主应用程序窗口后它是如何关闭的,VS都将正确退出调试模式。
  • 如果未显示导入视图(即FileDialog未返回任何可编辑的内容),则在关闭主应用程序窗口后,VS 将不会退出调试模式。

1 个答案:

答案 0 :(得分:1)

您的DI应该有composition root,其中99%的DI代码存在。工厂应该是1%依赖注入的情况。对于WPF that is the onStartup method

此外,我没有在您的代码中看到指定DI的生命周期管理部分的任何位置。如果您没有指定名为Bind<Samurai>().ToSelf().InSingletonScope();的终身管理,那么您可能无法获得终身管理而无需处置。 Here's the information on scopes for ninject

你说你在路上的某个地方添加了一个调用处理,但是如果你设置的事件监听器没有弱引用,那么可能会a memory leak导致缺乏处置。

最后您是否按照关联System.Environment.Exit问题的其他答案进行了操作? 检查调试器中的Application.Current.Windows集合以查找有问题的窗口。 https://stackoverflow.com/a/7349650/57883

您是否尝试过使用其他获胜表单对话框,或仅使用其他对话框来查看它是否可重现?