10

I'm trying to run an .NET Core Web application with EF Core. In order to test the repository I've added an MyDbContext that inherits the EF DbContext and interface IMyDbContext.

public interface IMyDbContext
{
    DbSet<MyModel> Models { get; set; }
}

public class MyDbContext : DbContext, IMyDbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
    {
    }

    public virtual DbSet<MyModel> Models { get; set; }
}

The context interface is injected to my generic repository:

public class GenericRepository<TEntity> : IGenericRepository<TEntity>
{
    private readonly IMyDbContext _context = null;

    public GenericRepository(IMyDbContext context)
    {
        this._context = context;
    }
}

When I use this code (without the interface) on startup.cs:

services.AddDbContext<MyDbContext>(options =>
     options.UseSqlServer(...));

I'm getting a run-time error of:

InvalidOperationException: Unable to resolve service for type 'IMyDbContext' while attempting to activate 'GenericRepository`1[MyModel]'

And when using this line of code:

services.AddDbContext<IMyDbContext>(options =>
     options.UseSqlServer(...));

I'm getting this compiled time error code of:

Cannot convert lambda expression to type 'ServiceLifetime' because it is not a delegate type

My question is how to properly configure the services.AddDbContext of ConfigureServices method? (Is there any changes needed inside Configure method?) If needed I'm willing to modify the IMyDbContext

Dariusz Woźniak
  • 9,640
  • 6
  • 60
  • 73
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91

2 Answers2

10

Use one of the overloads having 2 generic type arguments, which allow you to specify both the service interface/class you want to register as well as the DbContext derived class implementing it.

For instance:

services.AddDbContext<IMyDbContext, MyDbContext>(options =>
     options.UseSqlServer(...));
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Hey @Ivan, It looks like clean and nice answer but it creates an exception: `Could not resolve a service of type 'MyDbContext' for the parameter 'modelsDbContext' of method 'Configure' on type 'Startup'. Inner Exception 1: InvalidOperationException: No service for type 'MyDbContext' has been registered.` – Shahar Shokrani Jun 10 '19 at 20:03
  • 3
    Well, the above is all I can tell from EF Core point of view. The new exception indicates that you have direct dependency to `MyDbContext` in a code not shown in the post. – Ivan Stoev Jun 10 '19 at 20:21
5

Just found the answer:

I was missing the adding of the scope between IMyDbContext and MyDbContext.

public void ConfigureServices(IServiceCollection services)
{                    
    services.AddDbContext<MyDbContext>(options => options.UseSqlServer(...));
    services.AddScoped<IGenericRepository<MyModel>, GenericRepository<MyModel>>();
    services.AddScoped<IMyDbContext, MyDbContext>();
}
Shahar Shokrani
  • 7,598
  • 9
  • 48
  • 91