question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IFileProvider use case and abstraction issues

See original GitHub issue

From @dazinator on Monday, June 27, 2016 5:13:04 AM

Questioning whether the IFileProvider abstraction needs improving (or its implementations) - due to following issues. I am finding usage of the abstraction needs to be different for different providers, so in essence you have to cater for all specific implementations and the IFileProvider abstraction isn’t helpful.

Example use case…

I want an RC2 application to list all available CSS files that are themes for the application, so the user can select one and apply a theme to the site.

In order to distinguish a theme file from other files, the rule I am using is, it must live in a Css/Themes directory. However, in addition to supporting just physical files (from the web applications wwwroot/css/themes directory), the application should also support the ability for theme files to live within referenced projects within the solution.

Here is an example solution directory structure:

WebApplication/wwwroot/css/themes/theme1.css WebApplication/wwwroot/css/themes/theme2.css ModuleA/wwwroot/css/themes/moduleA.css ModuleB/wwwroot/css/themes/moduleB.css

In order to support files located in referenced projects, it means actually embedding the files into the assembly and using an EmbeddedFileProvider over those assemblies. CopyToOutput is useless because its non transitive

So to fulfil the use case, the application starts and creates an “EmbeddedFileProvider” for the referenced project assemblies, pointing to their “wwwroot” folders, as well as a PhysicalFileProvider for the main web applications “wwwroot” directory, and then wraps those in a CompositeFileProvider to give one IFileProvider instance that we can work with to query for Theme files…

Now given the IFileProvider instance, which is CompositeFileProvider we want to list the themes css files. If things were aligned it would be as simple as:

var allThemesFiles = fileProvider.GetDirectoryContents("css/themes")

And that would give you all files within that directory. However because EmbeddedFileProvider doesn’t support / preserve directory information, GetDirectoryContents doesn’t actually work - so we only get the PhysicalFiles when doing this. Well GetDirectoryContents does work for EmbeddedFileProvider but only for the root because it’s just a single directory, i.e fileProvider.GetDirectoryContents("") returns all files embedded in the assembly. So the application now has to worry about what Providers are in the CompositeProvider, and cater for specific ones like the EmbeddedFileProvider. For instance, for EmbeddedFileProvider it needs to loop through all files in the root (single directory) and try to determine if the originated from a css/themes directory based on the name - where “/” was replaced with “.”, i.e:

          // all embedded files actually just live in the root directory.
           var allFiles = fileProvider.GetDirectoryContents("");
            foreach (var file in allFiles)
            {
                if (file.Name.StartsWith("css.themes"))
                {
                    // theme?
                }
            }

Ofcourse, doing a fileProvider.GetDirectoryContents(""); on an IFileProvider (which is a composite in my example) could yield hundreds of files depending upon your application, and we don;t want to check all of those files with this logic which it is particular to Embedded files only. So in reality, this means we actually need to check the IFileProvider instance, cast it to a composite, check the providers it is wrapping, loop through them, upcast the Embedded ones, and then add our fileProvider.GetDirectoryContents(""); check to find the themes files differently for Embedded providers only.

This is just all yucky imho, is there not a better way? Finding someway to preserve directory information on compile (similar to preserveCompilationContext for dependencies information perhaps) and then restore from that at runtime, such that EmbeddedFileProvider could support directories would solve this imho.

For example, could we perhaps, at build / compile time, generate and embed a txt file, containing the preserved directory information for embedded files, (a manifest of sorts), and then use this special file at runtime to restore directory information to allow EmbeddedFileProvider to support directories again.

Copied from original issue: aspnet/FileSystem#206

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:20 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
dazinatorcommented, Dec 20, 2018

@Eilon this can be closed as there was a new manifest embedded file provider introduced to address this.

0reactions
Eiloncommented, Dec 20, 2018

Good catch, thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

IFileProvider use case and abstraction issues #825
Questioning whether the IFileProvider abstraction needs improving (or its implementations) - due to following issues. I am finding usage of the ...
Read more >
c# - Multiple file access abstractions
When using dependency injection for nearly everything it's good to have some file access abstraction. I find the idea of ASP.
Read more >
Improving your ASP.NET Core site's file handling capabilities
To solve this issue, we defined the following high-level steps: Abstract file management out to an IFileProvider interface; Update existing ...
Read more >
IFileProvider Interface (Microsoft.Extensions.FileProviders)
A read-only file provider abstraction.
Read more >
How to register IFileProvider for the dependency injection ...
I am getting the DI error when I try to use my service: Unable to resolve service for type 'Microsoft.Extensions.FileProviders.IFileProvider' ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found