Using IFileSysten
As part of 0004-file-system-abstraction
, NexusMods.Paths
now contains a file system abstraction:
IFileSystem
.
New code should make use of this abstraction, as it is required for Wine
(Windows on Linux) support.
Getting Started
Using dependency-injection, simply add IFileSystem
as a parameter to the constructor of your service:
public class MyService
{
private readonly IFileSystem _fileSystem;
public MyService(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
public async Task<int> GetCharCount(AbsolutePath textFile, CancellationToken cancellationToken = default)
{
var text = await _fileSystem.ReadAllTextAsync(textFile, cancellationToken);
return text.Length;
}
}
When writing unit tests, make sure to import NexusMods.Paths.TestingHelpers
in your test project.
And utilize AutoFileSystem
from AutoFixture:
public class MyServiceTests
{
[Theory, AutoFileSystem]
public async Task Test_GetCharCount(InMemoryFileSystem fs, AbsolutePath textFile, string contents)
{
fs.AddFile(textFile, contents);
var service = new MyService(fs);
var result = await service.GetCharCount(textFile);
result.Should.Be(contents.Length);
}
}
Accessing Special Folders
Everything file system and path related should be done using IFileSystem
.
This includes getting the path to "special" folders.
Instead of using Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
, use IFileSystem.GetKnownPath(KnownPath.ApplicationDataDirectory)
.
You should never use Environment.GetFolderPath
together with IFileSystem
because this will likely break path mappings.
If KnownPath
doesn't contain the path you need, open an issue or a PR to add this path.
Path Re-mappings
Path mappings are designed to be invisible to the API consumer and the IFileSystem
implementation,
they are completely isolated to BaseFileSystem
.
This design enables us to properly support virtual file systems, like Wine prefixes.
If a tool requests the user's documents directory using IFileSystem.GetKnownPath
, the implementation might
return:
C:\\Users\\{User}\\Documents
/home/{User}/Documents
/opt/wine/prefixes/my-cool-prefix/drive_c/Users/not-the-actual-user/Documents
.
The tool doesn't know, or care, what the actual concrete path is, the only thing it cares about, is the fact that this is a path to the 'documents' folder.
These mappings have to be manually created using IFileSystem.CreateOverlayFileSystem