Экземпляр DbContext не изменяется при внедрении зависимости - PullRequest
0 голосов
/ 29 октября 2019

В моем приложении у меня есть API и рабочий, которые оба должны использовать мою базу данных. У меня есть слой хранилища, доступ к которому оба из них. Я использую DI в своем приложении и внедряю свой dbContext в свои репозитории.

Хотя я ожидаю, что мои репозитории будут использовать новый dbContext при каждом запросе, экземпляр, кажется, всегда одинаков.

Поскольку у меня есть фоновый работник, который является одноэлементным, я не смог использовать время жизни моего dbContext по умолчанию. Поэтому я добавил свой dbContext как переходный как в моем рабочем, так и в моем API. Я добавил instanceId в мой dbContext, который установлен в моем конструкторе.

Конструктор dbcontext:

 public CatAPIDbContext()
    {
        InstanceId = Guid.NewGuid();
        Database.EnsureCreated();
    }

Работник configureservices:

  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 ConfigureServices:

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<>));
}

Пример GenericRepo:

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 () Я проверяю instanceId dbContext, и он всегда один и тот же в течение всей жизни моего приложения. В результате данные, которые я извлекаю из dbContext, устарели и не соответствуют текущему состоянию базы данных, поскольку dbContext никогда не удаляется. Я что-то не так делаю?

1 Ответ

0 голосов
/ 30 октября 2019

Как я вижу в вашем коде, вы сделали dbContext Transient, и это означает, что он создается новый экземпляр каждый раз, когда они вводятся или запрашиваются:

 services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Transient);

, если вы хотите иметь один экземплярдля всех запросов, сделайте так, чтобы он один раз попытался изменить ваш код, как показано ниже:

services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Singleton);

Но если вы хотите иметь один экземпляр для каждого запроса к приложению, попробуйте использовать время жизни с областью действия:

 services.AddDbContext<CatAPIDbContext>(ServiceLifetime.Scoped);
...