In one of my controllers, I have an async method that has to make a few db calls simultaneously, so I set it up like this:
public xxxController(IConfiguration configuration, xxxContext xxxContext, xxx2Context xxx2Context)
: base(xxxContext)
I store the contexts that are injected. In the particular method:
var v = await Task.WhenAll(... )
Inside of the WhenAll, I need to use the xxxContext for each item, so I get the non-thread safe exception.
What is the correct way to create a new DbContext? Right now I'm doing:
var v = new DbContextOptionsBuilder<xxxContext>();
v.UseSqlServer(_xxxContext.Database.GetDbConnection().ConnectionString);
xxContext e = new xxContext(v.Options);
So I'm getting the connection string from the existing context that was injected and use that to create a new one.
The connection strings are stored in appSettings.json. In the "ConnectionStrings" section.
Is there a cleaner way to create the contexts for multi-threading?
For this purpose I created something like factory class which can provide context per call. For your case it can be
public class AppDependencyResolver
{
private static AppDependencyResolver _resolver;
public static AppDependencyResolver Current
{
get
{
if (_resolver == null)
throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class");
return _resolver;
}
}
public static void Init(IServiceProvider services)
{
_resolver = new AppDependencyResolver(services);
}
private readonly IServiceProvider _serviceProvider;
private AppDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public xxxContext CreatexxxContextinCurrentThread()
{
var scopeResolver = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
return scopeResolver.ServiceProvider.GetRequiredService<xxxContext>();
}
}
Than you should call Init
method in Startup
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
AppDependencyResolver.Init(app.ApplicationServices);
//other configure code
}
You can look my approach for this on github