实体框架DbContext未使用依赖项注入进行处理



我在解决方案中有以下设置:

编辑:可以在此处找到演示解决方案

ASP.NET核心Web API:

public class MyController : ControllerBase
{
private readonly IMyService _service;
public MyController(IMyService service)
{
_service = service;
}
}

服务层:

public class MyService: IMyService, IDisposable
{
private readonly IDataContext _context;
public MyService(IDataContext context)
{
_context = context;
}
}

实体框架核心:

public class DataContext : DbContext, IDataContext, IDisposable
{
public DataContext(DbContextOptions<DataContext> options, IAuthenticationService authentication, ILogger<DataContext> logger) : base(options) 
{
...
}
}

使用Microsoft.Extensions.DependencyInjection:将其链接在一起的"CompositionRoot">

services.AddDbContext<DataContext>(options =>  options.UseSqlServer(configuration.GetConnectionString("myConnection")), ServiceLifetime.Transient);
services.AddTransient<IMyService, MyService>();
//EDIT: removed this line
//services.AddTransient<IDataContext, DataContext>(); 

这一切都如预期的那样工作,但我的DataContext从未被丢弃。我在dispose方法中添加了日志来监控这种行为,但我不明白为什么会发生这种情况(或者在这种情况下不会发生(。我试过

  • 重新排序"AddTransient"未成功(如预期(
  • 使用"AddScoped"而不是"AddTransient">

我在单元测试中使用一个接口来模拟DbContext,但我希望我的DbContext被处理掉。有人知道为什么会发生这种情况以及如何解决吗

编辑:一些额外的日志

  • 2020-03-24 21:09:29.5727 |在DataContext中注入的选项
  • 2020-03-24 21:09:29.6064|在DataContext中注入身份验证
  • 2020-03-24 21:09:29.6064|在DataContext中注入记录器
  • 2020-03-24 21:09:29.6262|创建的数据上下文1ddd98a1-a8f9-4096-8a11-c0b4d40d01ae
  • 2020-03-24 21:09:30.1918 |在客户服务中注入记录器
  • 2020-03-24 21:09:30.2200 |在CustomerService中注入DataContext
  • 2020-03-24 21:09:30.2300 |映射器在CustomerService中注入
  • 2020-03-24 21:09:30.2482|在CustomerService中注入身份验证
  • 2020-03-24 21:09:30.2482|创建客户服务5b446267-d908-4291-991-af11841324708
  • 2020-03-24 21:09:30.2769 |在CustomerController中注入记录器
  • 2020-03-24 21:09:30.2769 | CustomerService注入CustomerController
  • 2020-03-24 21:09:30.3186|CustomerController.GetCustomer(4(
  • 2020-03-24 21:09:35.0599 |处置客户服务5b446267-d908-4291-991-af11841324708

编辑3月25日:我尝试过在没有接口的情况下使用DataContext,但问题仍然存在。我真的不知道我做错了什么!

您没有正确注册DbContext

使用以下AddDbContext过载

services.AddDbContext<IDataContext, DataContext>(options =>  
options.UseSqlServer(configuration.GetConnectionString("myConnection")));

它将接口/抽象与具体实现相关联。

并删除临时注册

services.AddTransient<IDataContext, DataContext>();

也面临这个问题(实际上是问题吗?(。我有ASP.Net Core WebApi项目(framework=Net 5.0(,并使用AddDbContext将其注入MVC控制器。它应该将数据库上下文添加为";Scoped";文章称。根据我的预期,在这种情况下,数据库上下文应该根据每个http请求实例化(仅此而已(,并在MVC控制器生存期的范围内隐式处理,但由于某种原因,它不会发生。。潜在地,它可能导致";无法跟踪实体类型为{}的实例,因为已在跟踪另一个键值为{}的实例"(这是我来这里的原因(

我相信,它可以通过添加";使用";代码中的构造,或者像一样从控制器调用Dispose((

protected override void Dispose(bool disposing = true)
{
Console.WriteLine("Controller dispose.");
_dbContext.Dispose(); //your db-context (injected in controller)
base.Dispose(disposing);
}

但不确定这是正确的解决方案。。

最新更新