3

I want to register a scoped ICurrentUserService and then use it in the DbContext to set the CreatedBy property on every entity. I want it scoped because it uses the current HttpContext to get the user id from the claims and the HttpContext is scoped by definition.

services.AddTransient<ICurrentUserService, CurrentUserService>();

However when I try to use this with the DbContextFactory like this:

services.AddDbContextFactory<MyDbContext>(options =>
    options.UseSqlServer(config.ConnectionStrings.MSSQLConnection, x =>
        {
            x.MigrationsHistoryTable("...");
            x.MigrationsAssembly("...");
        }));

services.AddScoped<IMyDbContext>(provider => provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext());
services.AddScoped<MyDbContext>(provider => provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext());

I get the error

Cannot resolve scoped service 'SomeNamespace.ICurrentUserService' from root provider.

I can change it to Transient but that seems wrong and will probably be an issue later on for testing when I want to mock this and every class gets a new instance.

I'm actually not sure why Scoped does not work here. The DbContextFactory is registered Singleton but the Context is resolved as Scoped too.

Matthias
  • 1,267
  • 1
  • 15
  • 27

1 Answers1

4

Try it with ServiceLifetime.Scoped

services.AddDbContextFactory<ApplicationDbContext>(contextOptions => 
                    ... YOUR OPTIONS
), ServiceLifetime.Scoped);
x4k3p
  • 1,598
  • 2
  • 22
  • 42