ASP.Net Core注册DbContext后报错,非控制器层如何正确实例化?
解决ASP.NET Core业务层注入已配置DbContext的问题
问题出在哪?
你现在的核心问题是:虽然在Startup.cs里给MyContext配置了SqlServer连接并注册到了DI容器,但业务层MyManager却在手动new MyContext()——这会触发无参构造函数,而你既没在OnConfiguring里写配置,这个无参构造出来的上下文根本不知道该用哪个数据库,自然就抛System.InvalidOperationException了。而且用static存DbContext还会踩坑,DbContext是有状态的,长期驻留会引发并发和内存泄漏问题。
一步步改到正确姿势
1. 把业务层改成构造函数注入
先改掉MyManager里手动new的方式,让DI容器把配置好的MyContext传进来:
public class MyManager { private readonly MyContext _myContext; // 让DI通过构造函数注入上下文 public MyManager(MyContext myContext) { _myContext = myContext; } // 业务方法直接用这个注入的上下文就行 public async Task<List<YourEntity>> GetYourDataAsync() { return await _myContext.YourEntities.ToListAsync(); } }
划重点:别再用
static存DbContext!DbContext设计成短期使用的,静态字段会让它一直留在内存里,各种奇奇怪怪的问题都会找上门。
2. 把业务层也注册到DI容器
光改了MyManager还不够,得告诉DI容器怎么创建它的实例,在Startup.cs的ConfigureServices里加一行:
public void ConfigureServices(IServiceCollection services) { // 原来的DbContext注册,确保配置正确 services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("YourDbConn"))); // 注册业务层,推荐用Scoped(和DbContext默认生命周期一致,每个请求一个实例) services.AddScoped<MyManager>(); // 其他服务注册... }
3. 在需要的地方注入业务层
比如你的控制器要调用业务逻辑,同样用构造函数注入MyManager:
[ApiController] [Route("api/[controller]")] public class YourController : ControllerBase { private readonly MyManager _myManager; public YourController(MyManager myManager) { _myManager = myManager; } [HttpGet] public async Task<IActionResult> GetData() { var data = await _myManager.GetYourDataAsync(); return Ok(data); } }
额外要注意的小细节
- 你的
MyContext构造函数要确保带DbContextOptions<MyContext>的版本存在,这是DI注入配置的关键:public class MyContext : DbContext { // DI用的构造函数(必须有) public MyContext(DbContextOptions<MyContext> options) : base(options) { } // 无参构造可以留着,但别在业务代码里用(一般用来跑EF迁移) public MyContext() { } // 你的DbSet定义 public DbSet<YourEntity> YourEntities { get; set; } } - 检查
appsettings.json里的连接字符串是不是配对了:{ "ConnectionStrings": { "YourDbConn": "Server=.;Database=YourDatabaseName;Trusted_Connection=True;TrustServerCertificate=True;" } }
这样调整后,DI容器会一条龙搞定:创建配置好的MyContext,传给MyManager,再把MyManager传给控制器,再也不会出现数据库提供程序未配置的错误了。
内容的提问来源于stack exchange,提问作者Eutherpy
相关产品推荐
相关产品推荐

