ASP.NET Core 使用 AutoFac 注入 DbContext
ASP.NET Core 使用 AutoFac 注入 DbContext
DI 1.0 —— 通过 RegisterInstance
注入
一开始,并不是很懂 AutoFac 的用法,又因为要使用特定的构造器和参数来初始化 DbContext
,所以我想到的办法就是使用 RegisterInstance
,代码如下:
var optionsBuilder = new DbContextOptionsBuilder<BookListDbContext>();
optionsBuilder.UseMySql(connectionString, b => b.MigrationsAssembly("BookList.Domain"));
// SingleInstance 就是单例模式,现在想起来当时写的好智障
containerBuilder.RegisterInstance(new BookListDbContext(optionsBuilder.Options)).SingleInstance();
一开始在本地用 Swagger 一个一个的调试 api 的感觉还很好,没啥问题,后来前端同学把 js 加上,就会经常的出现 404。经过 debug 发现,是 DbContext
出现了冲突,多个请求同时访问同一个 DbContext
对象,造成异常,虽然不清楚为啥没有出现500而是404。
DI 2.0 —— 添加 IDbContext
接口,通过 RegisterType
注入
知道了问题所在,就想到了更换服务的生命周期设置,于是我在上面的代码的基础上直接把 SingleInstance
改成了 InstancePerLifetimeScope
,但在运行时遇到了异常,原来 RegisterInstance
仅支持 SingleInstance
。既然这样,那就接着换,于是我在网上发现了别人通过让自定义的 DbContext
实现一个 IDbContext
接口,进行依赖注入,代码如下:
// ··········· 省略 IDbContext 的定义
var optionsBuilder = new DbContextOptionsBuilder<BookListDbContext>();
optionsBuilder.UseMySql(connectionString, b => b.MigrationsAssembly("BookList.Domain"));
containerBuilder.RegisterType<MyDbContext>()
.As<IDbContext>()
.WithParam("options",optionsBuilder.Options)
.InstancePerLifetimeScope();
这样一来,我们就需要提取一个 IDbContext
,这个工作有些麻烦,但是在 ReSharper 的帮助下,简化了不少。然而,这个方法并没有生效,现在消费者类依赖 IDbContext
接口的一个实例,但是在实例化服务的时候却抛出了异常。。。
很蛋疼,刚刚提取出来的接口白费了。
DI 3.0 —— 使用 Register
方法
其实这个是我根据 Intellisence 试出来的,代码如下:
// 首先注册 options,供 DbContext 服务初始化使用
containerBuilder.Register(c =>
{
var optionsBuilder = new DbContextOptionsBuilder<BookListDbContext>();
optionsBuilder.UseMySql(connectionString, b => b
.MigrationsAssembly("BookList.Domain"));
return optionsBuilder.Options;
}).InstancePerLifetimeScope();
// 注册 DbContext
containerBuilder.RegisterType<BookListDbContext>()
.AsSelf()
.InstancePerLifetimeScope();
实验证明,这样注入 DbContext
是没有问题的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构