dependency-injection - DbContext 实例不随依赖注入而改变
问题描述
在我的应用程序中,我有一个 API 和一个 worker,它们都需要使用我的数据库。我有一个存储库层,这两个都可以访问。我在我的应用程序中使用 DI,并将我的 dbContext 注入到我的存储库中。
虽然我希望我的存储库对每个请求都使用新的 dbContext,但实例似乎总是相同的。
由于我有一个后台工作人员,它是一个单例,我无法使用我的 dbContext 的默认作用域生命周期。因此,我在我的工作人员和我的 API 中都将我的 dbContext 添加为瞬态。我已将 instanceId 添加到我的 dbContext 中,它是在我的构造函数中设置的。
dbcontext 的构造函数:
public CatAPIDbContext()
{
InstanceId = Guid.NewGuid();
Database.EnsureCreated();
}
工人配置服务:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Transient);
services.AddTransient(typeof(IFeedingProfileRepository), typeof(FeedingProfileRepository));
services.AddTransient(typeof(IFeedingTimesRepository), typeof(FeedingTimesRepository));
services.AddTransient(typeof(IFeedHistoryRepository), typeof(FeedHistoryRepository));
services.AddTransient(typeof(IMotorController), typeof(MotorController));
services.AddTransient(typeof(IFoodDispenser), typeof(FoodDispenser));
services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
services.AddTransient(typeof(IFeedingTimeChecker), typeof(FeedingTimeChecker));
services.AddHostedService<Worker>();
});
API 配置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddDbContext<CatAPIDbContext>();
services.AddTransient(typeof(IFeedingProfileRepository), typeof(FeedingProfileRepository));
services.AddTransient(typeof(IFeedingTimesRepository), typeof(FeedingTimesRepository));
services.AddTransient(typeof(IFeedHistoryRepository), typeof(FeedHistoryRepository));
services.AddTransient(typeof(IMotorController), typeof(MotorController));
services.AddTransient(typeof(IFoodDispenser), typeof(FoodDispenser));
services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
}
通用回购示例:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
public CatAPIDbContext _dbContext { get; set; }
public GenericRepository(CatAPIDbContext dbContext)
{
_dbContext = dbContext;
}
public T GetById(object id)
{
return _dbContext.Set<T>().Find(id);
}
}
我使用但没有获得最新状态示例的回购:
public class FeedingProfileRepository :
GenericRepository<FeedingProfile>, IFeedingProfileRepository
{
public FeedingProfileRepository(CatAPIDbContext dbContext) :
base(dbContext)
{
}
public FeedingProfile GetCurrentFeedingProfile()
{
var profile = _dbContext.FeedingProfiles
.Include(x => x.TimesToFeedOn)
.Where(x => x.CurrentlyActive == true).FirstOrDefault();
if (profile == null)
{
return null;
}
if (profile.TimesToFeedOn != null)
{
profile.TimesToFeedOn = profile.TimesToFeedOn.OrderByDescending(x => x.Time).ToList();
}
return profile;
}
}
当 thw orker 调用 FeedingProfileRepository.GetCurrentFeedingProfile() 时,我会检查 dbContext 的 instanceId,它在我的应用程序的整个生命周期中始终相同。结果,我从 dbContext 检索到的数据已经过时,并且与数据库的当前状态不匹配,因为 dbContext 永远不会被释放。难道我做错了什么?
解决方案
正如我在您的代码中看到的那样,您已经制作了 dbContext Transient ,这意味着每次注入或请求它们时都会创建一个新实例:
services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Transient);
如果您想为所有请求提供一个实例,请将其设为单例尝试更改您的代码,如下所示:
services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Singleton);
但是,如果您希望对应用程序的每个请求都有一个实例,请尝试使用作用域生命周期:
services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Scoped);
推荐阅读
- php - 无法访问 PHP/Twig 中命名数组键的值
- python - wxPython - 屏幕分辨率 3000x2000 和 DPI 200% 问题
- airflow - 如何从 SimpleHttpOperator 读取响应正文
- acumatica - 如何更正来自 Acuminator 的 PX1011 警告?(它建议密封类,但这会导致错误列表中的错误)
- javascript - THREE.js WebGLRenderer 画布消耗“点击”鼠标事件
- node.js - Nodejs逐行读取文件并将结果累积到全局对象中
- r - 在 Svydesign 对象中按十分位数计算平均值
- excel - 如果一个保留一个,如果更高,则在 Excel 中给出 2
- javascript - 为什么 javascript IF/ELSE 不能正常工作?
- cmd - 有没有办法在 Wix 项目中指定命令行别名?