Skip to main content

TypedPaths by Alex Chim

NuGet / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: TypedPaths

A Roslyn source generator that turns a folder tree into strongly typed path constants at compile time.

Author: Alex Chim

NuGet: https://www.nuget.org/packages/TypedPaths.Generator/

You can find more details at https://github.com/AlexChim1231/TypedPaths/

Source: https://github.com/AlexChim1231/TypedPaths/

Author

note

Alex Chim Alt text

Original Readme

note

TypedPaths.Generator

A Roslyn source generator that turns configured folder trees into strongly typed path constants at compile time. Each configured folder becomes a nested static class (for example Src, Template) so you can avoid magic strings.

What you get

Given a structure like:

/src
Template1.anyext
folderA/
Template2.anyext
folderB/
Template3.anyext
Template4.anyext
/template
email/
welcome.txt
sms/
otp.txt

the generator emits one file per root folder (TypedPaths.Src.g.cs, TypedPaths.Template.g.cs, ...), each defining a top-level static class in the TypedPaths namespace:

// TypedPaths.Src.g.cs
// <auto-generated/>
namespace TypedPaths;

public static class Src
{
public const string Value = "src";

public static class Template1
{
public const string Value = "src/Template1.anyext";
}

public static class FolderA
{
public const string Value = "src/folderA";

public static class Template2
{
public const string Value = "src/folderA/Template2.anyext";
}
}

public static class FolderB
{
public const string Value = "src/folderB";

public static class Template3
{
public const string Value = "src/folderB/Template3.anyext";
}

public static class Template4
{
public const string Value = "src/folderB/Template4.anyext";
}
}
}
// TypedPaths.Template.g.cs
// <auto-generated/>
namespace TypedPaths;

public static class Template
{
public const string Value = "template";

public static class Email
{
public const string Value = "template/email";

public static class Welcome
{
public const string Value = "template/email/welcome.txt";
}
}

public static class Sms
{
public const string Value = "template/sms";

public static class Otp
{
public const string Value = "template/sms/otp.txt";
}
}
}

With using TypedPaths; you can use Src.FolderA.Template2.Value and Template.Email.Welcome.Value instead of raw string paths.

Requirements
  • .NET 8 (or the TFM your project uses; the generator targets .NET Standard 2.0)
  • MSBuild / SDK-style projects
Setup

######### Option A: consume from NuGet (recommended)

<ItemGroup>
<PackageReference Include="TypedPaths.Generator" Version="1.0.0" />
</ItemGroup>

<ItemGroup>
<TypedPathsFolder Include="src" ClassName="Src" />
<TypedPathsFolder Include="template" />
</ItemGroup>

That is the only configuration needed in consumer projects.
TypedPaths.Generator.targets (from package build) automatically maps each TypedPathsFolder to AdditionalFiles for source generation.

######### Option B: local project reference (repository development)

<ItemGroup>
<ProjectReference Include="..\TypedPaths.Generator\TypedPaths.Generator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup>
<TypedPathsFolder Include="src" ClassName="Src" />
<TypedPathsFolder Include="template" />
</ItemGroup>

<Import Project="..\TypedPaths.Generator\build\TypedPaths.Generator.targets"
Condition="Exists('..\TypedPaths.Generator\build\TypedPaths.Generator.targets')" />

The explicit <Import /> is required only for local project-reference scenarios.

Build the project; the generator runs and adds TypedPaths.*.g.cs files to the compilation.

Usage in code

Add using TypedPaths; and use the generated classes directly. Each configured root folder becomes a top-level static class (e.g. Src, Template):

using TypedPaths;

// Always read .Value (works for both folder and file nodes)
string folderPath = Src.FolderA.Value; // "src/folderA"
string filePath = Src.FolderA.Template2.Value; // "src/folderA/Template2.anyext"
string emailTemplate = Template.Email.Welcome.Value; // "template/email/welcome.txt"

// e.g. resolve to full path
var fullPath = Path.Combine(projectRoot, Src.FolderA.Template2.Value);

Value is always a path relative to the project root:

  • Folder node Value = relative folder path
  • File node Value = relative file path (including extension)

Nested child classes are emitted only for folders (because only folders can contain files/subfolders).

Naming rules
  • Folder and file names become PascalCase identifiers.
  • Invalid identifier characters are dropped or split; leading digits get a _ prefix.
  • Duplicate names in the same scope get suffixes: _2, _3, etc.
  • Extensions are stripped from member names but kept in the path string.
  • If a folder name and file name conflict in the same scope:
    • the folder keeps the base name;
    • the file name becomes FileName + ExtensionWithoutDot (example: report/ + report.txt -> Report and ReportTxt);
    • if the conflicting file has no extension, use File suffix (example: data/ + data -> Data and DataFile).
Repository layout
ProjectDescription
TypedPaths.GeneratorThe source generator (Roslyn incremental generator).
TypedPaths.Generator.SampleExample app that uses the generator and runs a small demo.
TypedPaths.Generator.TestsUnit tests for the generator.
Build and test
dotnet restore
dotnet build
dotnet test

Run the sample:

dotnet run --project TypedPaths.Generator.Sample
License

See the repository for license information.

About

note

Generating strongly-typed paths for file system operations in C# projects.

How to use

Example (source csproj, source files)

This is the CSharp Project that references TypedPaths

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TypedPaths.Generator" Version="1.3.0" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<TypedPathsFolder Include="a" ClassName="Src" />
<!--<TypedPathsFolder Include="template" />-->
</ItemGroup>
</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <auto-generated/>

namespace TypedPaths;
public static class Src
{
public const string Value = "a";

public static class Andrei
{
public const string Value = "a/andrei.txt";
}
}

Useful

Download Example (.NET C#)

Share TypedPaths

https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths

Category "FilesToCode" has the following generators:

1 Chorn.EmbeddedResourceAccessGenerator Nuget GitHub Repo stars 2024-01-21

2 corecraft Nuget GitHub Repo stars 2024-02-17

3 Datacute.EmbeddedResourcePropertyGenerator Nuget GitHub Repo stars 2024-11-03

4 DotnetYang Nuget GitHub Repo stars 2024-06-29

5 EmbedResourceCSharp Nuget GitHub Repo stars 2023-04-16

6 kli.Localize Nuget GitHub Repo stars 2025-10-01

7 LingoGen Nuget GitHub Repo stars 2024-02-23

8 NFH.FileEmbed Nuget GitHub Repo stars 2025-08-08

9 NotNotAppSettings Nuget GitHub Repo stars 2024-01-26

10 Podimo.ConstEmbed Nuget GitHub Repo stars 2023-04-16

11 ResXGenerator Nuget GitHub Repo stars 2023-10-02

12 RSCG_JSON2Class Nuget GitHub Repo stars 2024-02-29

13 RSCG_Utils Nuget GitHub Repo stars 2023-04-16

14 Strings.ResourceGenerator Nuget GitHub Repo stars 2025-07-06

15 ThisAssembly_Resources Nuget GitHub Repo stars 2023-09-16

16 ThisAssembly.Strings Nuget GitHub Repo stars 2024-07-21

17 TypedPaths Nuget GitHub Repo stars 2026-04-01

18 Weave Nuget GitHub Repo stars 2024-01-27

See category

FilesToCode