Вызов Dispose у наследников DbContext в методах CRUD (EFCore 5)

Использую EFCore 5.0. Обычно делаю наследника от DbContext со свойствами DbSet<T>, а затем конкретные классы для работы с БД. Но, задумался на счет вызова Dispose у наследников DbContext в конкретных классах для работы с БД. Суть вопроса, как лучше реализовать классы для CRUD и избежать ошибок?

Я вижу три реализации, но не знаю какая из них наиболее успешная.

class ApplicationDbContext : DbContext
{
    public readonly string ConnectionString = "connection string was here :)";
    public ApplicationDbContext() : base() { }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(ConnectionString);
    }
        
    public DbSet<Cat> Cats { get; set; }
}
//1 способ, тут вообще не вызываю Dispose

class CatDataStore : IDataStore<Cat> //интерфейс IDataStore<T> требует реализации CRUD
{
   public async Task<bool> AddItem(Cat item)
   {
      ApplicationDbContext context = new ApplicationDbContext();
      await context.Cats.AddAsync(item);
      await _context.SaveChanesAsync();
      return await Task.FromResult(true);
   }

   //внизу по аналогии CRUD операции, внутри метода context без вызова Dispose
}
//2 способ, тут отдельно метод делаю Dispose в котором вызываю _context.Dispose()

class CatDataStore : IDataStore<Cat>
{
   private ApplicationDbContext _context = new ApplicationDbContext();
   public async Task<bool> AddItem(Cat item)
   {
      await _context.Cats.AddAsync(item);
      await _context.SaveChanesAsync();
      return Task.FromResult(true);
   }

   public void Dispose()
   {
      _context.Dispose();
   }
}
//3 способ, тут использую using в теле метода.

class CatDataStore : IDataStore<Cat>
{
   public async Task<bool> AddItem(Cat item)
   {
      using ApplicationDbContext context = new ApplicationDbContext();
      await context.Cats.AddAsync(item);
      await context.SaveChanesAsync();
      return Task.FromResult(true);
   }
}

Ответы (1 шт):

Автор решения: aepot

Реализуйте IDisposable.

Вот полная реализация IDisposable.

class CatDataStore : IDataStore<Cat>, IDisposable
{
    private ApplicationDbContext _context = new ApplicationDbContext();
    private bool disposed;

    public async Task<bool> AddItem(Cat item)
    {
        await _context.Cats.AddAsync(item);
        await _context.SaveChangesAsync();
        return true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SupressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (disposed)
                throw new ObjectDisposedException();
            _context.Dispose();
        }
        disposed = true;
    }

    ~CatDataStore() => Dispose(false);
}

Теперь вы делать можете так

using var store = new CatDataStore();
//...
→ Ссылка