Worker with Entity Framework repository base class

54 Views Asked by At

I would like to reuse the same base repository in ASP.NET Web API and also in a worker project. Of course in a worker we cannot use scoped services so need to make sure it is thread safe.

Is the example shown below thread safe to use when registering the context as a singleton?

Base repository class as shown (not whole class shown)

public class RepositoryBase<TContext> : IRepositoryBase<TContext> where TContext : DbContext, new()
{
    public Func<TContext> GetContext;

    public RepositoryBase()
    {
        GetContext = GetCurrentContext;
    }

    protected TContext GetCurrentContext()
    {
        return new TContext();
    }

    public IQueryable<TEntity> QueryAll<TEntity>() where TEntity : class
    {
        return GetDbSet<TEntity>().AsQueryable();
    }

    public void AddRange<TEntity>(IEnumerable<TEntity> entities) where TEntity : class
    {
        GetDbSet<TEntity>().AddRange(entities);
    }

    public async Task SaveChangesAsync()
    {
        await Context.SaveChangesAsync();
    }
}

Here is my worker repository base class

public class WorkerRepositoryBase<TContext> : RepositoryBase<TContext>, IWorkerRepositoryBase<TContext> where TContext : DbContext, new()
{
    private readonly IServiceProvider _serviceProvider;

    public WorkerRepositoryBase(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    protected override TContext GetCurrentContext()
    {
        using var scope = _serviceProvider.CreateScope();
        return scope.ServiceProvider.GetRequiredService<TContext>();
    }
}
2

There are 2 best solutions below

0
Ben On

Sorry for the silly question, I somehow missed that I CAN use scoped services in a worker.... https://learn.microsoft.com/en-us/dotnet/core/extensions/scoped-service?pivots=dotnet-7-0.

0
Felipe Gabriel Souza Martins On

Entity Framework Core, by default, is not thread-safe, so what you can do to improve this process is to use a per-request context, use a per-scope context in a Worker and ensure the correct elimination of the context, but your code is very good.