ASP.NET 项目里同时创建DbContext上下文实例和工厂的探索

本文探讨了在ASP.NETCore项目中同时使用DbContext注入和DbContextFactory的可行性,介绍了两者在依赖注入中的角色,以及如何解决因生命周期冲突导致的异常。作者强调了根据场景选择合适的方法,并注意可能带来的潜在问题和注意事项。
摘要由CSDN通过智能技术生成

一、思考

        为了应对不同的场景,为了解耦,在需要使用一个上下文实例的地方使用DbContext 注入,在需要创建使用多个上下文实例的地方使用DbContext工厂注入,那么在项目中同时通过依赖注入的方法将DbContext 和 DbContext Factory注入整个项目中是否可行?是否符合规范?

二、实践

        1、修改Program.cs文件,使用DI内置IOC容器实现依赖关系注入 DbContext 和 DbContext Factory,代码如下:

Program.cs

// 获取 IConfiguration 实例
var configuration = builder.Configuration;

//依赖关系注入 DbContext
builder.Services.AddDbContext<ApplicationDbContext>(
    options => options.UseSqlServer(configuration.GetConnectionString("BloggingDatabase"))
);
//依赖关系注入 DbContext 工厂
builder.Services.AddDbContextFactory<ApplicationDbContext>(
    options => options.UseSqlServer(configuration.GetConnectionString("BloggingDatabase"))
);

         2、运行项目,项目报错出现异常

        如果同时使用依赖注入DbContext 和 DbContext工厂,会出现下面的异常:

System.AggregateException:“Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.EntityFrameworkCore.IDbContextFactory`1[EF_CORE_TestProject.ApplicationDbContext] Lifetime: Singleton ImplementationType: Microsoft.EntityFrameworkCore.Internal.DbContextFactory`1[EF_CORE_TestProject.ApplicationDbContext]': Cannot consume scoped service 'Microsoft.EntityFrameworkCore.DbContextOptions`1[EF_CORE_TestProject.ApplicationDbContext]' from singleton 'Microsoft.EntityFrameworkCore.IDbContextFactory`1[EF_CORE_TestProject.ApplicationDbContext]'.)”

        上面异常的大概意思是:在使用ASP.NET Core的依赖注入容器时,尝试将一个作用域服务注入到单例服务中。这是因为作用域服务的生命周期比单例服务短,无法在单例服务中使用。是在配置Entity Framework Core的上下文工厂时出现了问题。可能是你尝试将DbContextOptions<ApplicationDbContext>作为作用域服务注入到了IDbContextFactory<ApplicationDbContext>的单例服务中。

        这是因为在使用AddDbContextFactory方法时,它会默认将上下文工厂注册为单例服务。而在代码中,同时又将ApplicationDbContext作为作用域服务注入到了上下文工厂中。要解决这个问题,可以将上下文选项配置为单例服务,以便在上下文工厂中使用。

修改代码如下:

builder.Services.AddDbContext<ApplicationDbContext>(
    options => options.UseSqlServer(configuration.GetConnectionString("BloggingDatabase")),
    ServiceLifetime.Singleton // 将上下文选项配置为单例服务
);

builder.Services.AddDbContextFactory<ApplicationDbContext>(
    options => options.UseSqlServer(configuration.GetConnectionString("BloggingDatabase"))
);

        运行项目无异常报错。

三、总结 

        从项目开发规范和代码规范的角度来看,同时将AddDbContextAddDbContextFactory两个方法用于同一个上下文类型是允许的。这样做可以满足不同的需求。

AddDbContext方法用于将上下文注册为服务,并且可以在需要直接使用上下文的地方进行依赖注入。它还负责管理上下文的生命周期。

AddDbContextFactory方法用于注册上下文工厂,它可以在需要创建多个上下文实例的地方使用。上下文工厂可以在需要时创建新的上下文实例,而不需要直接依赖于上下文。

        同时使用这两个方法的一个潜在问题是,如果你在代码中同时使用了上下文和上下文工厂,可能会导致一些混淆和冲突。因此,在使用时需要明确区分它们的使用场景和目的。另外,需要注意的是,如果你将上下文选项配置为单例服务,那么所有通过上下文工厂创建的上下文实例都将共享相同的上下文选项。这可能会导致一些意外的行为,特别是在多线程环境下。

        综上所述,同时使用AddDbContextAddDbContextFactory是允许的,但需要根据具体情况谨慎使用,并清楚它们的区别和适用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值