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。
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
接口的一个实例,但是在实例化服务的时候却抛出了异常。。。
很蛋疼,刚刚提取出来的接口白费了。
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
是没有问题的
ASP.NET Core 使用 AutoFac 注入 DbContext
原文:https://www.cnblogs.com/lonelyxmas/p/12900646.html