I have these layers:
- Repositories
- Services
- BlazorServer
In my BlazorServer, I have dependency injected IDbContextFactory, my repositories and services like below:
builder.Services.AddDbContextFactory<EstateDbContext>(OptionsHelper.ContextOptions(builder));
builder.Services.AddScoped<IRepository<Dealer>, EFRepository<Dealer, EstateDbContext>>();
builder.Services.AddScoped<IDealerService, DealerService>();
My repository example with GetTableAsync-method:
public sealed class EFRepository<T, TDbContext> : IRepository<T> where T : BaseEntity where TDbContext : DbContext
{
private readonly IDbContextFactory<TDbContext> contextFactory;
public EFRepository(IDbContextFactory<TDbContext> contextFactory)
{
this.contextFactory = contextFactory;
}
public async Task<IQueryable<T>> GetTableAsync(CancellationToken cancellationToken = default)
{
using TDbContext context = await contextFactory.CreateDbContextAsync(cancellationToken);
DbSet<T> table = context.Set<T>();
return table;
}
}
And my Services-layer, example with Get a list of 'Dealer'-entity:
public sealed class DealerService : IDealerService
{
private readonly IRepository<Dealer> dealerRepository;
public DealerService(IRepository<Dealer> dealerRepository)
{
this.dealerRepository = dealerRepository;
}
public async Task<List<Dealer>?> GetDealersAsync(CancellationToken cancellationToken = default)
{
IQueryable<Dealer> dealerQuery = await dealerRepository.GetTableAsync(cancellationToken);
List<Dealer> dealers = await dealerQuery.ToListAsync(cancellationToken);
return dealers;
}
}
Lastly, my Blazor Component:
@page "/dealers"
@inject IDealerService DealerService
<h1>Dealers</h1>
<div class="container bg-light p-3 mb-4 border">
@if (dealers is not null)
{
foreach (var dealer in dealers)
{
<p>@dealer.Name</p>
}
}
else
{
<p>Dealer is null</p>
}
</div>
@code {
private List<Dealer>? dealers;
protected override async Task OnInitializedAsync()
{
dealers = await DealerService.GetDealersAsync();
}
}
I have awaited everything all the way to the application layer, but I still get exception, how do I fix this one:
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'EstateDbContext'. |
Note: I have narrowed down my logic in the code above to be as simple as possible.
EDIT: I found the issue, but don't know how to solve it: in Repository, the using-statement is used on GetTableAsync()-method, and after the method is finished, the context is disposed, and then it can't be used in Service-layer... which causes the exception. How would I go about sending a IQueryable to the service layer without it being disposed?