我为基于ASP.NET MVC的应用程序编写集成测试,并且尝试解决ninject注册问题。
所以对于我的ASP.NET MVC注册,我有
kernel.Bind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InRequestScope();
为了澄清CustomDbContext,实现了IUnitOfWork和ICustomDbContext。
通过该注册,我保证每个CustomDbContext请求都有一个唯一的实例。该注册在ASP.NET范围内可以正常工作。
问题是当我编写集成测试时。
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
[Test]
public async Task Test()
{
// Arrange
var claaService = kernel.Get<IService>();
}
在设置步骤中,我加载了合成根目录(位于ASP.NET MVC项目中)。
问题是当我得到IService时(IService.cs的实现是Service.cs,并且该服务具有对IUnitOfWork.cs和IGenericRepository.cs的依赖。IGenericRepository.cs对ICustomDbContext的依赖)。
最后,当我访问IService时,我应该具有相同的CustomDbContext实例(正如我在MVC范围内所说的那样)。
我试图在子范围内解决它,但结果是相同的(它们仍然具有不同的哈希码):
using (var childKernel1 = new ChildKernel(kernel))
{
childKernel1.Rebind(typeof(ICustomDbContext), typeof(IUnitOfWork))
.ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
.InThreadScope();
var claaService = childKernel1.Get<IClassService>();
}
我的问题是:
为什么会这样呢?
我该如何解决(如果我不使用ninject,但我想用Ninject找到一种方法,即使我必须在集成测试中添加其他配置也可以)?
最佳答案
为什么会这样呢?
Ninject的作用域仅限于容器的使用寿命。您已设置要为每个[Test]创建的容器,因为您正在使用[SetUp]
。
此属性在TestFixture内部使用,以提供一组通用功能,这些功能在调用每种测试方法之前执行。
[SetUp]
public void SetUp()
{
kernel = NinjectConfig.CreateKernel();
}
如果要在同一个
[TestFixture]
中的多个测试中使用同一个容器(假设这是因为您说的“实例不相同”,但没有提及相同的内容),则需要使用[OneTimeSetup]
代替。该属性用于标识在夹具中执行任何测试之前被调用一次的方法。
[OneTimeSetUp]
public void OneTimeSetUp()
{
kernel = NinjectConfig.CreateKernel();
}
当然,这假设您所有相关的集成测试都在一个类中。
简而言之,您的Ninject容器在每次测试时都会被重新初始化,这意味着它管理的所有实例也都将被重新初始化。
关于c# - 为什么ninject在nunit中获得不同的Db实例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44407484/