I have an object were per group of users to manage concurrent changes in memory. At a fix rate, say every six seconds, I take the current state of the changes and apply it to the database. The important part is there is a separate thread that requires a dbcontext instance that is outside of the ASP.NET Core MVC LifeCycle. This makes it difficult, or I do not know how I can take advantage of indecency injection.
Is there a way to take advantage of the AddDbContextPool in this problem space. There doesn't seem to be a way to Rent a AppDbContext directly and Microsoft warns against creating AppDbContext directly as its API is likely to change. As far as I know, I don't have a way to inject/Rent my database context into the thread that is doing the work.
I'm handing the thread using Reactive API where I create a Subjects and use the Sample pipe line as the sample below shows:
UpdateSubject
.Sample(TimeSpan.FromSeconds(6))
.Subscribe(x => {
// This is where I'd like to take
// advantage of the dbcontext pooling
using(AppDbContext db = new AppDbContext){
// ...
// Iterate Over Changes
// ...
db.SaveChanges();
}
});
My current Perceived options are.
Asking the question helped me answer my own question, or find a solution. Everything below was tested with threads running outside of a request.
Turns out we can Inject the service provider to make our own instances through the API!
ReadOnly IServiceProvider _ServiceProvider;
MySingulation(IServiceProvider serviceProvider)
{
_ServiceProvider = serviceProvider;
}
Once we have a handle to IServiceProvider through injection, we can use MVC Core API to create instances of our context
using(var serviceScope = _ServiceProvider.CreateScope())
{
// Don't get confused -- Call GetService from the serviceScope and
// not directly from the member variable _ServiceProvider.
var context = serviceScope.ServiceProvider.GetService<YourAppDbContext>();
// ...
// Make use of the dbcontext
// ...
}
Now, it just important to remember we make use of MVC Core Pooling in the Startup.cs to begin with.
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddDbContextPool<YourAppDbContext>(options => {
options.UseSqlServer(settings.Connection);
});
// Oh, it's important the singultion was created within Core's LifeCycle/API
services.AddSingleton<MySingulation>();
//...
}