Invex.FileSystem 2.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Invex.FileSystem --version 2.0.0
                    
NuGet\Install-Package Invex.FileSystem -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Invex.FileSystem" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Invex.FileSystem" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Invex.FileSystem" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Invex.FileSystem --version 2.0.0
                    
#r "nuget: Invex.FileSystem, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Invex.FileSystem@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Invex.FileSystem&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Invex.FileSystem&version=2.0.0
                    
Install as a Cake Tool

Invex.FileSystem

Build NuGet License: MIT .NET

A strongly-typed file system abstraction for .NET that layers build-aware path resolution and reversible file transformations on top of System.IO.Abstractions. Stop hard-coding paths and scattering magic strings across your build and tooling code: resolve well-known locations by key, compose paths fluently, and make temporary, automatically-rolled-back edits to files.

Features

  • Rooted paths. RootedPath carries its own IFileSystem, so paths and I/O always travel together, and composes fluently with the / operator.
  • Keyed path resolution. Resolve locations such as "Root" or "Artifacts" through a prioritized chain of IPathProvider implementations, with results cached after the first lookup.
  • Strongly-typed path markers. Give compile-time names to well-known paths via IPathMarker instead of relying on magic strings.
  • Reversible file transforms. TransformFileScope and TransformMultiFileScope apply temporary edits to one or many files and restore the originals on dispose, or commit them with CancelRestore().
  • Dependency-injection first. A single AddRootedFileSystem() call wires everything up; register custom providers with ProvidePath(...).
  • Testable. Everything works against IFileSystem, so a MockFileSystem drops straight into your tests.

Installation

dotnet add package Invex.FileSystem

The package targets .NET 10.0. It depends on System.IO.Abstractions, Microsoft.Extensions.DependencyInjection.Abstractions and Microsoft.Extensions.Hosting.Abstractions. The rooted file system logs path resolutions through ILogger, so register logging (for example services.AddLogging()) in your container. Generic-host apps already have both; a standalone console or build tool also needs the Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Logging packages for BuildServiceProvider() and AddLogging():

dotnet add package Microsoft.Extensions.DependencyInjection
dotnet add package Microsoft.Extensions.Logging

Quick start

Register the file system with your DI container and declare where your well-known paths live:

using Invex.FileSystem;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddLogging();

// Register the rooted file system.
services.AddRootedFileSystem();

// Describe where your well-known paths live.
services.ProvidePath((key, fs) => key switch
{
    "Root"      => fs.CurrentDirectory,
    "Artifacts" => fs.GetPath("Root") / "artifacts",
    _           => null,
});

using var provider = services.BuildServiceProvider();
var fs = provider.GetRequiredService<IRootedFileSystem>();

// Resolve and compose paths.
RootedPath artifacts = fs.GetPath("Artifacts");
RootedPath logFile   = artifacts / "logs" / "build.log";

if (!logFile.PathExists)
    fs.Directory.CreateDirectory(artifacts);

Usage

Compose and query paths

A RootedPath binds an absolute path string to the IFileSystem it belongs to, so existence checks and queries need no extra context. It implicitly converts to string for any API that expects one:

RootedPath path = fs.GetPath("Root") / "src" / "Project.csproj";

bool exists        = path.PathExists;   // file or directory
RootedPath? parent = path.Parent;       // null at the root

File.ReadAllText(path);

See Rooted Paths.

Resolve well-known locations by key

IRootedFileSystem.GetPath(string) queries every registered IPathProvider in descending priority order and caches the first non-null result. Use the (key, fs) overload of ProvidePath when a path depends on another resolved path:

services.ProvidePath((key, fs) => key == "Output"
    ? fs.GetPath("Root") / "output"
    : null, priority: 5);

See Path Providers.

Name paths with types

Implement IPathMarker when a path is statically determined by a type. Markers bypass the provider chain and cache:

public sealed class ArtifactsPath : IPathMarker
{
    public static RootedPath Path(IFileSystem fileSystem) =>
        ((IRootedFileSystem)fileSystem).GetPath("Root") / "artifacts";
}

RootedPath artifacts = fs.GetPath<ArtifactsPath>();

See Path Markers.

Patch files temporarily

TransformFileScope captures a file's content, applies a transform and restores the original when the scope is disposed. TransformMultiFileScope does the same for a set of files:

await using (var scope = await TransformFileScope.CreateAsync(
    fs.GetPath("Root") / "Directory.Build.props",
    content => content.Replace("1.0.0", "2.0.0")))
{
    // The file now contains "2.0.0"; run your build step here.
}
// On dispose the original content is restored automatically.

See File Transform Scopes.

Test without touching the disk

Construct a RootedPath over a MockFileSystem, or override the keyed "RootedFileSystem" registration in your container:

var mock = new MockFileSystem();
var path = new RootedPath(mock, "/repo/file.txt");

mock.AddFile(path, new MockFileData("hello"));
// path.FileExists is now true

See Testing.

Documentation

Full documentation: https://invex-games.github.io/filesystem/

Guide Contents
Introduction What the library solves, when to use it, and the pieces at a glance.
Getting Started Installation, DI registration, and your first resolved paths.
Rooted Paths Creating, composing and querying RootedPath.
Path Providers Priorities, caching, custom providers and error handling.
Path Markers Strongly-typed paths with IPathMarker.
File Transform Scopes Temporary, reversible single- and multi-file edits.
Testing Using MockFileSystem with rooted paths and transform scopes.
API Reference Every public type, with links into the generated reference.

Development

dotnet build Invex.FileSystem.slnx
dotnet test Invex.FileSystem.slnx

The documentation site is built with DocFX through the Atom build in _atom/:

atom BuildDocs   # generate the site
atom ServeDocs   # build and serve it locally

Without the atom tool installed, run the same targets with dotnet run --project _atom -- BuildDocs.

License

Licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Invex.FileSystem:

Package Downloads
Invex.Atom.Build

An opinionated task and build automation framework

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 32 10/15/2026
2.1.0-rc.2 30 10/15/2026
2.0.0 472 10/14/2026
2.0.0-rc.31 30 10/14/2026
2.0.0-rc.29 38 10/14/2026
2.0.0-rc.27 35 10/14/2026
2.0.0-rc.23 32 10/14/2026
2.0.0-rc.20 30 10/14/2026
2.0.0-rc.18 41 10/14/2026
2.0.0-rc.16 33 10/14/2026
1.5.0-rc.8 41 10/13/2026
1.5.0-rc.2 76 9/11/2026
1.4.0 1,395 8/31/2026
1.4.0-rc.8 79 8/28/2026
1.4.0-rc.6 79 8/21/2026
1.4.0-rc.4 89 8/14/2026
1.4.0-rc.2 76 8/7/2026
1.3.0 6,818 8/3/2026
1.3.0-rc.6 80 8/3/2026
1.3.0-rc.4 75 7/24/2026
Loading failed