What's the correct way to register/resolve a DbContext by an Interface?
I have multiple web services with a different dbcontext each.
Since I need to write some common functionalities in a shared project, I wrote an interface which is implemented by each dbcontext, so I can have the set of shared functionalities "dbcontext-implementation-agnostic" just injecting the dbcontext interface.
In each project, each dbcontext is already used and injected by its implementation , but I would like to use just its interface in the common features project.
So, in each webservice I would have something like:
services.AddDbContext<IMyDbcontext, MyDbcontext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("MyDbContext"));
});
services.AddTransient<ISharedService, SharedService>();
and in the shared project
public class SharedService : ISharedService
{
public SharedService(IMydbcontext context)
{
[...]
}
[...]
}
having IMyDbcontext
just like
public interface IMyDbcontext
{
DbSet<SharedSettings> Settings { get; set; }
int SaveChanges(bool acceptAllChangesOnSuccess);
int SaveChanges();
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default);
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
and I require ISharedService within Startup.cs - Configure() with
app.ApplicationServices.GetService<ISharedService>();
I've been googling a lot and tried different approches but I couldn't find one which worked...
I've tried to use a forwarder, like this: (as suggested here )
services.AddDbContext<MyDbContext>();
services.AddScoped<IMyDbContext>(provider => provider.GetRequiredService<MyDbContext>());
But, while I've no issues resolving the concrete MyDbContext
, I get this error whenever I try to resolve IMyDbContext
System.InvalidOperationException: 'Cannot resolve 'Blah.IMyService' from root provider because it requires scoped service 'Blah.IMydbcontext'.'
where IMyService
is registered as transient and it's implementation constructor is
public MyService(IMydbcontext context)
I also tried to register the dbcontext like this
services.AddDbContext<IMyDbContext, MyDbContext>();
but then, when I try to resolve MyDbContext
i get null
, and I can't understand why
As pointed out by /u/AngularBeginner :
The
IMyService
requires a scopedIMyDbContext
, but within your startups Configure() method you don't have a scope.You can make your
IDbContext
transient (if that's acceptable to you).Alternatively you can try to create a temporary scope using the
CreateScope()
method, then get your IMyService from that new scoped provider.
So, I created a scope with IServiceScopeFactory and it did the trick
var scopeFactory = app.ApplicationServices.GetService<IServiceScopeFactory>();
using var scope = scopeFactory.CreateScope();
var myService = scope.ServiceProvider.GetService<IMyService>();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.