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
.
AddDbContext
defaults to using a scoped lifestyle:
Scoped lifetime services are created once per request.
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.
来源:https://stackoverflow.com/questions/46327364/getting-dbcontext-when-resolving-a-singleton