(这个问题最初是在Ninject Google小组中提出的,但我现在看到Stackoverflow似乎更活跃。)
我正在使用NamedScopeExtension将相同的ViewModel注入到View和Presenter中。在View被释放后,内存分析显示ViewModel仍然由Ninject缓存保留。如何使Ninject释放ViewModel?当窗体关闭和处理时,所有ViewModel都会被释放,但我正在使用工厂在窗体中创建和删除控件,并希望ViewModel能够被垃圾回收(Presenter和View也会被回收)。
请参见以下使用dotMemoryUnit的单元测试,以说明该问题:
using System;
using FluentAssertions;
using JetBrains.dotMemoryUnit;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ninject;
using Ninject.Extensions.DependencyCreation;
using Ninject.Extensions.NamedScope;
namespace UnitTestProject
{
[TestClass]
[DotMemoryUnit(FailIfRunWithoutSupport = false)]
public class UnitTest1
{
[TestMethod]
public void TestMethod()
{
// Call in sub method so no local variables are left for the memory profiling
SubMethod();
// Assert
dotMemory.Check(m =>
{
m.GetObjects(w => w.Type.Is<ViewModel>()).ObjectsCount.Should().Be(0);
});
}
private static void SubMethod()
{
// Arrange
var kernel = new StandardKernel();
string namedScope = "namedScope";
kernel.Bind<View>().ToSelf()
.DefinesNamedScope(namedScope);
kernel.DefineDependency<View, Presenter>();
kernel.Bind<ViewModel>().ToSelf()
.InNamedScope(namedScope);
kernel.Bind<Presenter>().ToSelf()
.WithCreatorAsConstructorArgument("view");
// Act
var view = kernel.Get<View>();
kernel.Release(view);
}
}
public class View
{
public View()
{
}
public View(ViewModel vm)
{
ViewModel = vm;
}
public ViewModel ViewModel { get; set; }
}
public class ViewModel
{
}
public class Presenter
{
public View View { get; set; }
public ViewModel ViewModel { get; set; }
public Presenter(View view, ViewModel viewModel)
{
View = view;
ViewModel = viewModel;
}
}
}
dotMemory.Check断言失败,并且在分析快照时,ViewModel引用了Ninject缓存。我认为当View释放时,应该释放命名范围。
敬礼, Andreas
kernel.Release
方法甚至不会调用对象的Dispose
方法,它只会将对象从缓存中移除。 - BatteryBackupUnit