В моем приложении у меня есть API и рабочий процесс, которым нужно использовать мою базу данных. У меня есть слой репозитория, к которому обращаются оба из них. Я использую DI в своем приложении и добавляю свой dbContext в свои репозитории.
Хотя я ожидаю, что мои репозитории будут использовать новый dbContext при каждом запросе, экземпляр всегда будет одним и тем же.
Поскольку у меня есть фоновый рабочий, который является синглтоном, я не смог использовать заданное по умолчанию время жизни моего dbContext. Поэтому я добавил свой dbContext как временный как в моем рабочем, так и в моем API. Я добавил 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;
}
}
Когда сервер вызывает FeedingProfileRepository.GetCurrentFeedingProfile(), я проверяю instanceId dbContext, и он всегда один и тот же в течение всего времени существования моего приложения. В результате данные, которые я извлекаю из dbContext, устарели и не соответствуют текущему состоянию базы данных, поскольку dbContext никогда не удаляется. Я делаю что-то неправильно?