Reputation: 3274
Within ConfigureServices
I have
services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
as well as
services.AddSingleton<IMyModel>(s =>
{
var dbContext = s.GetService<MyContext>();
var lastItem= dbContext.Items.LastOrDefault();
return new MyModel(lastItem);
});
But s.GetService<MyContext>()
throws an error:
Cannot resolve scoped service 'MyContext' from root provider.
How can I achieve that? I don't want to inject MyDbContext
in MyModel
contructor as it is in a library which should have no reason to know about Entity Framework
.
Upvotes: 6
Views: 7316
Reputation: 93273
AddDbContext
defaults to using a scoped lifestyle:
Scoped lifetime services (AddScoped) are created once per client request (connection).
The reason an error is being thrown is that you're attempting to obtain an instance of MyContext
from outside of a request. As the error message suggests, it is not possible to obtain a scoped service from the root IServiceProvider
.
For your purposes, you can create a scope explicitly and use that for your dependency resolution, like so:
services.AddSingleton<IMyModel>(sp =>
{
using (var scope = sp.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<MyContext>();
var lastItem = dbContext.Items.LastOrDefault();
return new MyModel(lastItem);
}
});
This code above creates a scoped IServiceProvider
that can be used for obtaining scoped services.
Upvotes: 16