(This question was first asked in the Ninject Google Group, but I see now that Stackoverflow seems to be more active.)
I'm using the NamedScopeExtension to inject the same ViewModel into both the View and the Presenter. After the View have been released, memory profiling shows that the ViewModel is still retained by the Ninject cache. How can I make Ninject release the ViewModel? All ViewModels are released when the Form is Closed and Disposed, but I'm creating and deleting Controls using a Factory in the Form and would like the ViewModels be garbage collected to (the Presenter and View gets collected).
See the following UnitTest, using dotMemoryUnit, for an illustration of the problem:
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;
}
}
}
The dotMemory.Check assert fails and when analyzing the snapshot the ViewModel has references to the Ninject cache. I thought the named scope should be released when the View was released.
Regards, Andreas