I write integration tests for ASP.NET MVC based application, and I try to resolve ninject registration issue.
So for my ASP.NET MVC registration I have
kernel.Bind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InRequestScope();
Just to clarify CustomDbContext implements IUnitOfWork and ICustomDbContext.
With that registration i guarantee that i have one unique instance per request for CustomDbContext. That registration works properly in scope of ASP.NET.
The problem is when i write integration tests.
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
[Test]
public async Task Test()
{
// Arrange
var claaService = kernel.Get<IService>();
}
On set up step i load my composition root (which is in ASP.NET MVC project).
The problem is when i get IService (Implementation of IService.cs is Service.cs and that service has dependencies to IUnitOfWork.cs and IGenericRepository.cs. IGenericRepository.cs has dependency to ICustomDbContext).
At the end when i access IService i should have same instance of CustomDbContext (and as I said in works in scope of MVC).
I have tried to resolve it in child scope, but the result is the same (they still have different hash code):
using (var childKernel1 = new ChildKernel(kernel))
{
childKernel1.Rebind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InThreadScope();
var claaService = childKernel1.Get<IClassService>();
}
My questions are:
- Why this is happening ?
- How can I resolve it (it works if i do not use ninject, but i want to find a way with Ninject, even if i have to add additional configuration in integration tests) ?
Ninject's scoping is limited to the lifetime of the container. You have setup the container to be created for each [Test] because you are using
[SetUp].If you want to use the same container across multiple tests in the same
[TestFixture](assuming this because you said "instance is not the same", but you didn't mention same as what), you need to use[OneTimeSetup]instead.This of course assumes all of your relevant integration tests are in a single class.
In short, your Ninject container is being re-initialized on every test, which means all instances it manages are also being re-initialized.