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>());
options.FileProviders.Add(fileProvider);
});
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
?
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 once
inside 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).