Injecting DbContext into FileProvider in ASP.NET Core dependency-injection entity-framework-core razor


I am trying to load some of the views from the database as described in here. So I want to use EF Core in the File provider.

RazorViewEngineOptions has a FileProviders property that you can add your file provider to. The problem is that you have to give it an instace of the file provider. So you'll need to instantiate all of the file providers' dependencies right there in Startup's ConfigureServices method.

Currently I inject an instance of IServiceProvider into the Configure method of Startup. Then I store the instance in a field (called _serviceProvider):

IServiceProvider _serviceProvider;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider provider)
   _serviceProvider = provider;

Then in ConfigureServices I use that field to instanciate the UIDbContext.

services.Configure<RazorViewEngineOptions>(options =>
    var fileProvider = new DbFileProvider(_serviceProvider.GetService<UIDbContext>());

Is there any better way to be able to inject the UIDbContext into the DbFileProvider constructor Or any way to instantiate a UIDbContext inside DbFileProvider without IServiceProvider?

7/23/2017 9:37:27 AM

Accepted Answer

You don't want to use DbContext as a file provider source the way you did.

DbContext isn't thread-safe, so it won't work when you have one single DbContext instance for the whole provider, because multiple requests could call the DbContext and it's operation more than once at the same time, resulting in exception when trying to execute 2 queries in parallel.

You'd have to instantiate a connection (like in the linked article) or DbContext per IFileInfo/IDirectoryContents instance.

DbContextOptions<UIDbContext> should be registered as singleton, so you can resolve it onceinside Configure` w/o any issues and pass it to your provider.

Alternatively you can also call DbContextOptionsBuilder and build/construct a DbContextOptions<T>, but then you have to repeat the configuration for you did inside AddDbContext (i.e. .UseSqlServer()).

However it can be useful, as it allows you to set different settings (i.e. changing the way how includes, errors etc. are logged).

7/23/2017 7:21:38 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow