From 22d2c0d4a23808ad8689bda8725aba44ffd208f9 Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Thu, 2 Apr 2026 21:44:45 +0300 Subject: [PATCH 1/3] first --- v2/RSCGExamplesData/GeneratorDataRec.json | 6 +++++ v2/rscg_examples/TypedPaths/description.json | 22 +++++++++++++++++++ .../TypedPaths/src/FolderToCode.slnx | 3 +++ .../src/FolderToCode/FolderToCode.csproj | 20 +++++++++++++++++ .../TypedPaths/src/FolderToCode/Program.cs | 2 ++ .../TypedPaths/src/FolderToCode/a/andrei.txt | 0 6 files changed, 53 insertions(+) create mode 100644 v2/rscg_examples/TypedPaths/description.json create mode 100644 v2/rscg_examples/TypedPaths/src/FolderToCode.slnx create mode 100644 v2/rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj create mode 100644 v2/rscg_examples/TypedPaths/src/FolderToCode/Program.cs create mode 100644 v2/rscg_examples/TypedPaths/src/FolderToCode/a/andrei.txt diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json index 77cb342d1..4ac4a9393 100644 --- a/v2/RSCGExamplesData/GeneratorDataRec.json +++ b/v2/RSCGExamplesData/GeneratorDataRec.json @@ -1564,5 +1564,11 @@ "Category": 46, "dtStart": "2026-03-18T00:00:00", "show": true + }, + { + "ID":"TypedPaths", + "Category": 8, + "dtStart": "2026-04-01T00:00:00", + "show": true } ] \ No newline at end of file diff --git a/v2/rscg_examples/TypedPaths/description.json b/v2/rscg_examples/TypedPaths/description.json new file mode 100644 index 000000000..dd16b70b2 --- /dev/null +++ b/v2/rscg_examples/TypedPaths/description.json @@ -0,0 +1,22 @@ +{ + "generator":{ + "name":"TypedPaths", + "nuget":[ + "https://www.nuget.org/packages/TypedPaths/" + ], + "link":"https://github.com/AlexChim1231/TypedPaths", + "author":"Alex Chim", + "source":"https://github.com/AlexChim1231/TypedPaths" + }, + "data":{ + "goodFor":["Generating strongly-typed paths for file system operations in C# projects."], + "csprojDemo":"FolderToCode.csproj", + "csFiles":["Program.cs"], + "excludeDirectoryGenerated":[""], + "includeAdditionalFiles":[""] + }, + "links":{ + "blog":"", + "video":"" + } +} \ No newline at end of file diff --git a/v2/rscg_examples/TypedPaths/src/FolderToCode.slnx b/v2/rscg_examples/TypedPaths/src/FolderToCode.slnx new file mode 100644 index 000000000..9feecc1be --- /dev/null +++ b/v2/rscg_examples/TypedPaths/src/FolderToCode.slnx @@ -0,0 +1,3 @@ + + + diff --git a/v2/rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj b/v2/rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj new file mode 100644 index 000000000..7f5940a33 --- /dev/null +++ b/v2/rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj @@ -0,0 +1,20 @@ + + + + Exe + net10.0 + enable + enable + + + + + + true + $(BaseIntermediateOutputPath)\GX + + + + + + diff --git a/v2/rscg_examples/TypedPaths/src/FolderToCode/Program.cs b/v2/rscg_examples/TypedPaths/src/FolderToCode/Program.cs new file mode 100644 index 000000000..998b7e555 --- /dev/null +++ b/v2/rscg_examples/TypedPaths/src/FolderToCode/Program.cs @@ -0,0 +1,2 @@ +Console.WriteLine("Hello, World!"); +Console.WriteLine(TypedPaths.Src.Andrei.Value); diff --git a/v2/rscg_examples/TypedPaths/src/FolderToCode/a/andrei.txt b/v2/rscg_examples/TypedPaths/src/FolderToCode/a/andrei.txt new file mode 100644 index 000000000..e69de29bb From 409de31187644b95dec546016019e90f2b02c30b Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Thu, 2 Apr 2026 21:52:59 +0300 Subject: [PATCH 2/3] added --- README.md | 30 +- later.md | 2 +- v2/.tours/TypedPaths.tour | 36 ++ v2/Generator/MultiGeneratorV2.cs | 12 +- v2/Generator/all.csv | 1 + v2/rscg_examples/TypedPaths/description.json | 4 +- v2/rscg_examples/TypedPaths/readme.txt | 204 ++++++++++ v2/rscg_examples/TypedPaths/video.json | 39 ++ .../docs/Authors/Alex_Chim.md | 7 + .../docs/Categories/FilesToCode.md | 6 +- .../docs/Categories/_PrimitiveFilesToCode.mdx | 4 +- .../docs/RSCG-Examples/TypedPaths.md | 375 ++++++++++++++++++ .../docs/RSCG-Examples/index.md | 13 +- v2/rscg_examples_site/docs/about.md | 2 +- v2/rscg_examples_site/docs/indexRSCG.md | 5 +- .../src/components/HomepageFeatures/index.js | 2 +- .../static/exports/RSCG.json | 8 + 17 files changed, 732 insertions(+), 18 deletions(-) create mode 100644 v2/.tours/TypedPaths.tour create mode 100644 v2/rscg_examples/TypedPaths/readme.txt create mode 100644 v2/rscg_examples/TypedPaths/video.json create mode 100644 v2/rscg_examples_site/docs/Authors/Alex_Chim.md create mode 100644 v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md diff --git a/README.md b/README.md index fe0587392..87da7f408 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# RSCG - 258 Examples of Roslyn Source Code Generators / 16 created by Microsoft / +# RSCG - 259 Examples of Roslyn Source Code Generators / 16 created by Microsoft / -The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 258 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. +The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 259 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem -## Latest Update : 2026-03-18 => 18 March 2026 +## Latest Update : 2026-04-01 => 01 April 2026 If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)*** @@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt ## Content -Those are the 258 Roslyn Source Code Generators that I have tested you can see and download source code example. +Those are the 259 Roslyn Source Code Generators that I have tested you can see and download source code example. ( including 16 from Microsoft ) +### 259. [TypedPaths](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths) , in the [FilesToCode](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#filestocode) category + +Generated on : 2026-04-01 => 01 April 2026 + +
+ Expand + + + +Author: Alex Chim + + + +Nuget: [https://www.nuget.org/packages/TypedPaths/](https://www.nuget.org/packages/TypedPaths/) + + +Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths) + +Source: [https://github.com/AlexChim1231/TypedPaths/](https://github.com/AlexChim1231/TypedPaths/) + +
+ ### 258. [REslava.ResultFlow](https://ignatandrei.github.io/RSCG_Examples/v2/docs/REslava.ResultFlow) , in the [Documentation](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#documentation) category Generated on : 2026-03-18 => 18 March 2026 diff --git a/later.md b/later.md index 8e613a736..78d912786 100644 --- a/later.md +++ b/later.md @@ -1,6 +1,6 @@ # Just later -## Latest Update : 2026-03-18 => 18 March 2026 +## Latest Update : 2026-04-01 => 01 April 2026 diff --git a/v2/.tours/TypedPaths.tour b/v2/.tours/TypedPaths.tour new file mode 100644 index 000000000..0756e7e94 --- /dev/null +++ b/v2/.tours/TypedPaths.tour @@ -0,0 +1,36 @@ + +{ + "$schema": "https://aka.ms/codetour-schema", + "title": "TypedPaths", + "steps": + [ + { + "file": "rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj", + "description": "First, we add Nuget [TypedPaths](https://www.nuget.org/packages/TypedPaths/) in csproj ", + "pattern": "TypedPaths" + } + + ,{ + "file": "rscg_examples/TypedPaths/src/FolderToCode/Program.cs", + "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj ", + "pattern": "this is the code" + } + + + ,{ + "file": "rscg_examples/TypedPaths/src/FolderToCode/obj/GX/TypedPaths.Generator/TypedPaths.Generator.Generator/TypedPathsAttribute.g.cs", + "description": "Generated File 2 from 2 : TypedPathsAttribute.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/TypedPaths/src/FolderToCode/obj/GX/TypedPaths.Generator/TypedPaths.Generator.Generator/TypedPaths.Src.g.cs", + "description": "Generated File 1 from 2 : TypedPaths.Src.g.cs ", + "line": 1 + } + + ], + + "ref": "main" + +} \ No newline at end of file diff --git a/v2/Generator/MultiGeneratorV2.cs b/v2/Generator/MultiGeneratorV2.cs index 9f3cc333e..de7821394 100644 --- a/v2/Generator/MultiGeneratorV2.cs +++ b/v2/Generator/MultiGeneratorV2.cs @@ -339,7 +339,17 @@ public async Task GrabDescriptionFromNuget() Console.WriteLine($"grab data from {url}"); var response = await _client.GetAsync(url); var data=await response.Content.ReadAsStringAsync(); - var answer= JsonDocument.Parse(data); + Console.WriteLine($"{namePackage}: {data}"); + JsonDocument answer; + try + { + answer = JsonDocument.Parse(data); + } + catch(Exception ex) + { + Console.WriteLine($"cannot parse json from {url} for {namePackage} because {ex.Message}"); + return ""; + } var items = answer.RootElement.GetProperty("items"); foreach (var item in items.EnumerateArray()) { diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv index 8cb5fd822..cef41b3e9 100644 --- a/v2/Generator/all.csv +++ b/v2/Generator/all.csv @@ -257,3 +257,4 @@ Nr,Key,Source,Category 256,Sundew.DiscriminatedUnions, https://github.com/sundews/Sundew.DiscriminatedUnions,FunctionalProgramming 257,Pekspro.DataAnnotationValuesExtractor, https://github.com/pekspro/DataAnnotationValuesExtractor,EnhancementClass 258,REslava.ResultFlow, https://github.com/reslava/nuget-package-reslava-result/,Documentation +259,TypedPaths, https://github.com/AlexChim1231/TypedPaths/,FilesToCode diff --git a/v2/rscg_examples/TypedPaths/description.json b/v2/rscg_examples/TypedPaths/description.json index dd16b70b2..9c653ff04 100644 --- a/v2/rscg_examples/TypedPaths/description.json +++ b/v2/rscg_examples/TypedPaths/description.json @@ -4,9 +4,9 @@ "nuget":[ "https://www.nuget.org/packages/TypedPaths/" ], - "link":"https://github.com/AlexChim1231/TypedPaths", + "link":"https://github.com/AlexChim1231/TypedPaths/", "author":"Alex Chim", - "source":"https://github.com/AlexChim1231/TypedPaths" + "source":"https://github.com/AlexChim1231/TypedPaths/" }, "data":{ "goodFor":["Generating strongly-typed paths for file system operations in C# projects."], diff --git a/v2/rscg_examples/TypedPaths/readme.txt b/v2/rscg_examples/TypedPaths/readme.txt new file mode 100644 index 000000000..7239bfaea --- /dev/null +++ b/v2/rscg_examples/TypedPaths/readme.txt @@ -0,0 +1,204 @@ +# 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: + +```csharp +// TypedPaths.Src.g.cs +// +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"; + } + } +} +``` + +```csharp +// TypedPaths.Template.g.cs +// +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) + +```xml + + + + + + + + +``` + +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) + +```xml + + + + + + + + + + +``` + +The explicit `` 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`): + +```csharp +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 + + +| Project | Description | +| ----------------------------- | ---------------------------------------------------------- | +| `TypedPaths.Generator` | The source generator (Roslyn incremental generator). | +| `TypedPaths.Generator.Sample` | Example app that uses the generator and runs a small demo. | +| `TypedPaths.Generator.Tests` | Unit tests for the generator. | + + +## Build and test + +```bash +dotnet restore +dotnet build +dotnet test +``` + +Run the sample: + +```bash +dotnet run --project TypedPaths.Generator.Sample +``` + +## License + +See the repository for [license](LICENSE) information. \ No newline at end of file diff --git a/v2/rscg_examples/TypedPaths/video.json b/v2/rscg_examples/TypedPaths/video.json new file mode 100644 index 000000000..ff0c1f43f --- /dev/null +++ b/v2/rscg_examples/TypedPaths/video.json @@ -0,0 +1,39 @@ +{ + "scriptName": "TypedPaths", + "steps": +[ + {"typeStep":"exec","arg":"clipchamp.exe launch"}, + {"typeStep":"text","arg": "Welcome to Roslyn Examples"}, + {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"}, + {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"}, + {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "}, + +{"typeStep":"text","arg": "Today I will present TypedPaths . Generating strongly-typed paths for file system operations in C# projects. ."}, +{"typeStep":"browser","arg":"https://www.nuget.org/packages/TypedPaths/"}, +{"typeStep":"text","arg": "The whole example is here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths"}, +{"typeStep":"text","arg": "You can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths#download-example-net--c-"}, +{"typeStep":"text","arg":"Here is the code downloaded "}, +{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"}, +{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "}, +{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"}, + +{"typeStep":"text","arg": "To use it ,you will put the Nuget TypedPaths into the csproj "}, + +{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\TypedPaths\\src\\FolderToCode\\FolderToCode.csproj"}, + +{"typeStep":"text","arg": "And now I will show you an example of using TypedPaths"}, + +{"typeStep":"hide","arg": "now execute the tour in VSCode"}, +{"typeStep":"tour", "arg": "src/.tours/"}, +{"typeStep":"text","arg":" And I will execute the project"}, +{"typeStep":"showproj", "arg":"FolderToCode.csproj"}, +{"typeStep":"text","arg":" This concludes the project"}, +{"typeStep":"waitseconds","arg":"30"}, +{"typeStep":"text","arg": "Remember, you can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths#download-example-net--c-", +SpeakTest=" "}, +{"typeStep":"waitseconds","arg":"30"}, +] +} diff --git a/v2/rscg_examples_site/docs/Authors/Alex_Chim.md b/v2/rscg_examples_site/docs/Authors/Alex_Chim.md new file mode 100644 index 000000000..dfe4181b3 --- /dev/null +++ b/v2/rscg_examples_site/docs/Authors/Alex_Chim.md @@ -0,0 +1,7 @@ +# Author : Alex Chim + +Number RSCG: 1 + + + 1 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + diff --git a/v2/rscg_examples_site/docs/Categories/FilesToCode.md b/v2/rscg_examples_site/docs/Categories/FilesToCode.md index ca6e7a876..5ece18907 100644 --- a/v2/rscg_examples_site/docs/Categories/FilesToCode.md +++ b/v2/rscg_examples_site/docs/Categories/FilesToCode.md @@ -1,6 +1,6 @@

FilesToCode

-Number RSCG: 17 +Number RSCG: 18 1 [Chorn.EmbeddedResourceAccessGenerator](/docs/Chorn.EmbeddedResourceAccessGenerator) [![Nuget](https://img.shields.io/nuget/dt/Chorn.EmbeddedResourceAccessGenerator?label=Chorn.EmbeddedResourceAccessGenerator)](https://www.nuget.org/packages/Chorn.EmbeddedResourceAccessGenerator/) ![GitHub Repo stars](https://img.shields.io/github/stars/ChristophHornung/EmbeddedResourceGenerator?style=social) 2024-01-21 @@ -34,5 +34,7 @@ Number RSCG: 17 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 17 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 + 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + + 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx index bdc5483fa..f2135ae40 100644 --- a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx +++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx @@ -32,7 +32,9 @@ 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 17 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 + 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + + 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 ### See category diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md b/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md new file mode 100644 index 000000000..b1bad0bb8 --- /dev/null +++ b/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md @@ -0,0 +1,375 @@ +--- +sidebar_position: 2590 +title: 259 - TypedPaths +description: Generating strongly-typed paths for file system operations in C# projects. +slug: /TypedPaths +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import TOCInline from '@theme/TOCInline'; +import SameCategory from '../Categories/_PrimitiveFilesToCode.mdx'; + +# TypedPaths by Alex Chim + + + + +## NuGet / site data +[![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) +[![GitHub last commit](https://img.shields.io/github/last-commit/AlexChim1231/TypedPaths?label=updated)](https://github.com/AlexChim1231/TypedPaths/) +![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) + +## Details + +### Info +:::info + +Name: **TypedPaths** + + + +Author: Alex Chim + +NuGet: +*https://www.nuget.org/packages/TypedPaths/* + + +You can find more details at https://github.com/AlexChim1231/TypedPaths/ + +Source: https://github.com/AlexChim1231/TypedPaths/ + +::: + +### Author +:::note +Alex Chim +![Alt text](https://github.com/AlexChim1231.png) +::: + +## 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: + +```csharp +// TypedPaths.Src.g.cs +// +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"; + } + } +} +``` + +```csharp +// TypedPaths.Template.g.cs +// +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) + +```xml + + + + + + + + +``` + +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) + +```xml + + + + + + + + + + +``` + +The explicit `` 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`): + +```csharp +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 + + +| Project | Description | +| ----------------------------- | ---------------------------------------------------------- | +| `TypedPaths.Generator` | The source generator (Roslyn incremental generator). | +| `TypedPaths.Generator.Sample` | Example app that uses the generator and runs a small demo. | +| `TypedPaths.Generator.Tests` | Unit tests for the generator. | + + +## Build and test + +```bash +dotnet restore +dotnet build +dotnet test +``` + +Run the sample: + +```bash +dotnet run --project TypedPaths.Generator.Sample +``` + +## License + +See the repository for [license](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** +```xml showLineNumbers {10} + + + + Exe + net10.0 + enable + enable + + + + + + true + $(BaseIntermediateOutputPath)\GX + + + + + + + +``` + + + + + + This is the use of **TypedPaths** in *Program.cs* + +```csharp showLineNumbers +Console.WriteLine("Hello, World!"); +Console.WriteLine(TypedPaths.Src.Andrei.Value); + +``` + + + + +### Generated Files + +Those are taken from $(BaseIntermediateOutputPath)\GX + + + + +```csharp showLineNumbers +// + +namespace TypedPaths; +public static class Src +{ + public const string Value = "a"; + + public static class Andrei + { + public const string Value = "a/andrei.txt"; + } +} + +``` + + + + +```csharp showLineNumbers +namespace TypedPaths + { + [System.AttributeUsage(System.AttributeTargets.Class)] + internal class TypedPathAttribute : System.Attribute \{ } + } +``` + + + + +## Useful + +### Download Example (.NET C#) + +:::tip + +[Download Example project TypedPaths ](/sources/TypedPaths.zip) + +::: + + +### Share TypedPaths + + + +https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths + + + diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md index 74ec37779..947a83d9e 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md @@ -1,7 +1,7 @@ --- sidebar_position: 30 -title: 258 RSCG list by category -description: 258 RSCG list by category +title: 259 RSCG list by category +description: 259 RSCG list by category slug: /rscg-examples --- @@ -879,7 +879,7 @@ import DocCardList from '@theme/DocCardList'; ## FilesToCode
- Expand FilesToCode =>examples:17 + Expand FilesToCode =>examples:18 @@ -965,6 +965,11 @@ import DocCardList from '@theme/DocCardList'; [kli.Localize](/docs/kli.Localize) + + + +[TypedPaths](/docs/TypedPaths) +
@@ -1943,6 +1948,8 @@ flowchart LR; FilesToCode--> kli.Localize((kli.Localize)) + FilesToCode--> TypedPaths((TypedPaths)) + FunctionalProgramming--> dunet((dunet)) FunctionalProgramming--> PartiallyApplied((PartiallyApplied)) diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md index 8f16d39db..df2316294 100644 --- a/v2/rscg_examples_site/docs/about.md +++ b/v2/rscg_examples_site/docs/about.md @@ -6,7 +6,7 @@ title: About ## Content You will find here code examples -of 258 Roslyn Source Code Generator (RSCG) +of 259 Roslyn Source Code Generator (RSCG) that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look. ## Are those examples ready for production? diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md index 9fb3f0f2f..956d78c3e 100644 --- a/v2/rscg_examples_site/docs/indexRSCG.md +++ b/v2/rscg_examples_site/docs/indexRSCG.md @@ -7,9 +7,9 @@ slug: /List-of-RSCG import useBaseUrl from '@docusaurus/useBaseUrl'; -## 258 RSCG with examples in descending chronological order +## 259 RSCG with examples in descending chronological order -This is the list of 258 ( 16 from Microsoft) RSCG with examples +This is the list of 259 ( 16 from Microsoft) RSCG with examples [See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx) @@ -20,6 +20,7 @@ This is the list of 258 ( 16 from Microsoft) RSCG with examples | No | Name | Date | Category | | --------- | ----- | ---- | -------- | +|259| [TypedPaths by Alex Chim ](/docs/TypedPaths)|2026-04-01 => 01 April 2026 | [FilesToCode](/docs/Categories/FilesToCode) | |258| [REslava.ResultFlow by Rafa Eslava ](/docs/REslava.ResultFlow)|2026-03-18 => 18 March 2026 | [Documentation](/docs/Categories/Documentation) | |257| [Pekspro.DataAnnotationValuesExtractor by Pekspro ](/docs/Pekspro.DataAnnotationValuesExtractor)|2026-02-15 => 15 February 2026 | [EnhancementClass](/docs/Categories/EnhancementClass) | |256| [Sundew.DiscriminatedUnions by Kim Hugener Ohlsen ](/docs/Sundew.DiscriminatedUnions)|2026-02-14 => 14 February 2026 | [FunctionalProgramming](/docs/Categories/FunctionalProgramming) | diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js index a140bdc05..16c8761e8 100644 --- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js +++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js @@ -4,7 +4,7 @@ import styles from './styles.module.css'; const FeatureList = [ { -title: '258 Examples (16 from MSFT)', +title: '259 Examples (16 from MSFT)', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json index fe21b788b..ec3e7eb9d 100644 --- a/v2/rscg_examples_site/static/exports/RSCG.json +++ b/v2/rscg_examples_site/static/exports/RSCG.json @@ -2065,6 +2065,14 @@ "Source": "https://github.com/reslava/nuget-package-reslava-result/", "Category": "Documentation", "AddedOn": "2026-03-18T00:00:00" + }, + { + "Name": "TypedPaths", + "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths", + "NuGet": "https://www.nuget.org/packages/TypedPaths/", + "Source": "https://github.com/AlexChim1231/TypedPaths/", + "Category": "FilesToCode", + "AddedOn": "2026-04-01T00:00:00" } ] } \ No newline at end of file From 9514a8f4b83e2a65fefeb94974031387803f90b6 Mon Sep 17 00:00:00 2001 From: Andrei Ignat Date: Thu, 2 Apr 2026 21:59:09 +0300 Subject: [PATCH 3/3] links --- README.md | 4 +- v2/.tours/TypedPaths.tour | 4 +- v2/book/examples/TypedPaths.html | 58 ++++++++++++++++++ v2/book/list.html | 6 +- v2/book/pandocHTML.yaml | 1 + v2/rscg_examples/TypedPaths/description.json | 2 +- v2/rscg_examples/TypedPaths/nuget.txt | 1 + v2/rscg_examples/TypedPaths/video.json | 8 +-- .../docs/Authors/Alex_Chim.md | 2 +- .../docs/Categories/FilesToCode.md | 2 +- .../docs/Categories/_PrimitiveFilesToCode.mdx | 2 +- .../docs/RSCG-Examples/TypedPaths.md | 30 ++++----- .../static/exports/RSCG.json | 2 +- .../static/exports/RSCG.xlsx | Bin 13677 -> 13719 bytes .../static/sources/TypedPaths.zip | Bin 0 -> 980 bytes 15 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 v2/book/examples/TypedPaths.html create mode 100644 v2/rscg_examples/TypedPaths/nuget.txt create mode 100644 v2/rscg_examples_site/static/sources/TypedPaths.zip diff --git a/README.md b/README.md index 87da7f408..e299010cf 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ Generated on : 2026-04-01 => 01 April 2026 Author: Alex Chim - +A Roslyn source generator that turns a folder tree into strongly typed path constants at compile time. -Nuget: [https://www.nuget.org/packages/TypedPaths/](https://www.nuget.org/packages/TypedPaths/) +Nuget: [https://www.nuget.org/packages/TypedPaths.Generator/](https://www.nuget.org/packages/TypedPaths.Generator/) Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths) diff --git a/v2/.tours/TypedPaths.tour b/v2/.tours/TypedPaths.tour index 0756e7e94..f00252708 100644 --- a/v2/.tours/TypedPaths.tour +++ b/v2/.tours/TypedPaths.tour @@ -6,8 +6,8 @@ [ { "file": "rscg_examples/TypedPaths/src/FolderToCode/FolderToCode.csproj", - "description": "First, we add Nuget [TypedPaths](https://www.nuget.org/packages/TypedPaths/) in csproj ", - "pattern": "TypedPaths" + "description": "First, we add Nuget [TypedPaths.Generator](https://www.nuget.org/packages/TypedPaths.Generator/) in csproj ", + "pattern": "TypedPaths.Generator" } ,{ diff --git a/v2/book/examples/TypedPaths.html b/v2/book/examples/TypedPaths.html new file mode 100644 index 000000000..36fb1045f --- /dev/null +++ b/v2/book/examples/TypedPaths.html @@ -0,0 +1,58 @@ + +

RSCG nr 259 : TypedPaths

+ +

Info

+Nuget : https://www.nuget.org/packages/TypedPaths/ + +

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

+ +

Author :Alex Chim

+ +

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

+ +

About

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

+ How to use +

+

+ Add reference to the TypedPaths in the csproj +

+ + +

This was for me the starting code

+ +
+ I have coded the file Program.cs +
+ +
+

And here are the generated files

+ +
+ The file generated is TypedPaths.Src.g.cs +
+ + +
+ The file generated is TypedPathsAttribute.g.cs +
+ + +

+ You can download the code and this page as pdf from + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths + +

+ + +

+ You can see the whole list at + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG + +

+ diff --git a/v2/book/list.html b/v2/book/list.html index 434352200..c141807a5 100644 --- a/v2/book/list.html +++ b/v2/book/list.html @@ -17,7 +17,7 @@

-This is the list of 258 RSCG with examples => +This is the list of 259 RSCG with examples =>

@@ -1058,6 +1058,10 @@

+ + + +
258 REslava.ResultFlow
259TypedPaths
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml index a82883f05..20b8d311d 100644 --- a/v2/book/pandocHTML.yaml +++ b/v2/book/pandocHTML.yaml @@ -272,6 +272,7 @@ input-files: - examples/Sundew.DiscriminatedUnions.html - examples/Pekspro.DataAnnotationValuesExtractor.html - examples/REslava.ResultFlow.html +- examples/TypedPaths.html # or you may use input-file: with a single value # defaults: diff --git a/v2/rscg_examples/TypedPaths/description.json b/v2/rscg_examples/TypedPaths/description.json index 9c653ff04..2a5ce50e8 100644 --- a/v2/rscg_examples/TypedPaths/description.json +++ b/v2/rscg_examples/TypedPaths/description.json @@ -2,7 +2,7 @@ "generator":{ "name":"TypedPaths", "nuget":[ - "https://www.nuget.org/packages/TypedPaths/" + "https://www.nuget.org/packages/TypedPaths.Generator/" ], "link":"https://github.com/AlexChim1231/TypedPaths/", "author":"Alex Chim", diff --git a/v2/rscg_examples/TypedPaths/nuget.txt b/v2/rscg_examples/TypedPaths/nuget.txt new file mode 100644 index 000000000..8cae0e5a2 --- /dev/null +++ b/v2/rscg_examples/TypedPaths/nuget.txt @@ -0,0 +1 @@ +A Roslyn source generator that turns a folder tree into strongly typed path constants at compile time. \ No newline at end of file diff --git a/v2/rscg_examples/TypedPaths/video.json b/v2/rscg_examples/TypedPaths/video.json index ff0c1f43f..62726bf03 100644 --- a/v2/rscg_examples/TypedPaths/video.json +++ b/v2/rscg_examples/TypedPaths/video.json @@ -8,8 +8,8 @@ {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"}, {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "}, -{"typeStep":"text","arg": "Today I will present TypedPaths . Generating strongly-typed paths for file system operations in C# projects. ."}, -{"typeStep":"browser","arg":"https://www.nuget.org/packages/TypedPaths/"}, +{"typeStep":"text","arg": "Today I will present TypedPaths.Generator . Generating strongly-typed paths for file system operations in C# projects. ."}, +{"typeStep":"browser","arg":"https://www.nuget.org/packages/TypedPaths.Generator/"}, {"typeStep":"text","arg": "The whole example is here"}, {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths"}, {"typeStep":"text","arg": "You can download the code from here"}, @@ -19,11 +19,11 @@ {"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "}, {"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"}, -{"typeStep":"text","arg": "To use it ,you will put the Nuget TypedPaths into the csproj "}, +{"typeStep":"text","arg": "To use it ,you will put the Nuget TypedPaths.Generator into the csproj "}, {"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\TypedPaths\\src\\FolderToCode\\FolderToCode.csproj"}, -{"typeStep":"text","arg": "And now I will show you an example of using TypedPaths"}, +{"typeStep":"text","arg": "And now I will show you an example of using TypedPaths.Generator"}, {"typeStep":"hide","arg": "now execute the tour in VSCode"}, {"typeStep":"tour", "arg": "src/.tours/"}, diff --git a/v2/rscg_examples_site/docs/Authors/Alex_Chim.md b/v2/rscg_examples_site/docs/Authors/Alex_Chim.md index dfe4181b3..91d542587 100644 --- a/v2/rscg_examples_site/docs/Authors/Alex_Chim.md +++ b/v2/rscg_examples_site/docs/Authors/Alex_Chim.md @@ -3,5 +3,5 @@ Number RSCG: 1 - 1 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + 1 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 diff --git a/v2/rscg_examples_site/docs/Categories/FilesToCode.md b/v2/rscg_examples_site/docs/Categories/FilesToCode.md index 5ece18907..8d104ca86 100644 --- a/v2/rscg_examples_site/docs/Categories/FilesToCode.md +++ b/v2/rscg_examples_site/docs/Categories/FilesToCode.md @@ -34,7 +34,7 @@ Number RSCG: 18 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx index f2135ae40..9090622be 100644 --- a/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx +++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveFilesToCode.mdx @@ -32,7 +32,7 @@ 16 [ThisAssembly.Strings](/docs/ThisAssembly.Strings) [![Nuget](https://img.shields.io/nuget/dt/ThisAssembly.Strings?label=ThisAssembly.Strings)](https://www.nuget.org/packages/ThisAssembly.Strings/) ![GitHub Repo stars](https://img.shields.io/github/stars/devlooped/ThisAssembly?style=social) 2024-07-21 - 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 + 17 [TypedPaths](/docs/TypedPaths) [![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) 2026-04-01 18 [Weave](/docs/Weave) [![Nuget](https://img.shields.io/nuget/dt/Weave?label=Weave)](https://www.nuget.org/packages/Weave/) ![GitHub Repo stars](https://img.shields.io/github/stars/otac0n/Weave?style=social) 2024-01-27 diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md b/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md index b1bad0bb8..191fcb83b 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/TypedPaths.md @@ -15,7 +15,7 @@ import SameCategory from '../Categories/_PrimitiveFilesToCode.mdx'; ## NuGet / site data -[![Nuget](https://img.shields.io/nuget/dt/TypedPaths?label=TypedPaths)](https://www.nuget.org/packages/TypedPaths/) +[![Nuget](https://img.shields.io/nuget/dt/TypedPaths.Generator?label=TypedPaths.Generator)](https://www.nuget.org/packages/TypedPaths.Generator/) [![GitHub last commit](https://img.shields.io/github/last-commit/AlexChim1231/TypedPaths?label=updated)](https://github.com/AlexChim1231/TypedPaths/) ![GitHub Repo stars](https://img.shields.io/github/stars/AlexChim1231/TypedPaths?style=social) @@ -26,12 +26,12 @@ import SameCategory from '../Categories/_PrimitiveFilesToCode.mdx'; 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/* +*https://www.nuget.org/packages/TypedPaths.Generator/* You can find more details at https://github.com/AlexChim1231/TypedPaths/ @@ -49,11 +49,11 @@ Alex Chim ## Original Readme :::note -# TypedPaths.Generator +### 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 +###### What you get Given a structure like: @@ -148,14 +148,14 @@ public static class Template With `using TypedPaths;` you can use `Src.FolderA.Template2.Value` and `Template.Email.Welcome.Value` instead of raw string paths. -## Requirements +###### Requirements - .NET 8 (or the TFM your project uses; the generator targets .NET Standard 2.0) - MSBuild / SDK-style projects -## Setup +###### Setup -### Option A: consume from NuGet (recommended) +######### Option A: consume from NuGet (recommended) ```xml @@ -171,7 +171,7 @@ With `using TypedPaths;` you can use `Src.FolderA.Template2.Value` and `Template 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) +######### Option B: local project reference (repository development) ```xml @@ -193,7 +193,7 @@ The explicit `` 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 +###### 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`): @@ -215,7 +215,7 @@ var fullPath = Path.Combine(projectRoot, Src.FolderA.Template2.Value); Nested child classes are emitted only for folders (because only folders can contain files/subfolders). -## Naming rules +###### Naming rules - Folder and file names become **PascalCase** identifiers. - Invalid identifier characters are dropped or split; leading digits get a `_` prefix. @@ -226,7 +226,7 @@ Nested child classes are emitted only for folders (because only folders can cont - 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 +###### Repository layout | Project | Description | @@ -236,7 +236,7 @@ Nested child classes are emitted only for folders (because only folders can cont | `TypedPaths.Generator.Tests` | Unit tests for the generator. | -## Build and test +###### Build and test ```bash dotnet restore @@ -250,9 +250,9 @@ Run the sample: dotnet run --project TypedPaths.Generator.Sample ``` -## License +###### License -See the repository for [license](LICENSE) information. +See the repository for [license](https://github.com/AlexChim1231/TypedPaths//LICENSE) information. ::: diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json index ec3e7eb9d..9c020af9d 100644 --- a/v2/rscg_examples_site/static/exports/RSCG.json +++ b/v2/rscg_examples_site/static/exports/RSCG.json @@ -2069,7 +2069,7 @@ { "Name": "TypedPaths", "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/TypedPaths", - "NuGet": "https://www.nuget.org/packages/TypedPaths/", + "NuGet": "https://www.nuget.org/packages/TypedPaths.Generator/", "Source": "https://github.com/AlexChim1231/TypedPaths/", "Category": "FilesToCode", "AddedOn": "2026-04-01T00:00:00" diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx index 2eefef579fd860a9b1fe35738364e8ca4e566757..859822196f3d670e47896d90d73bd1dc61b331bd 100644 GIT binary patch delta 12561 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 delta 12471 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 IJpZx#e+lw50ssI2 diff --git a/v2/rscg_examples_site/static/sources/TypedPaths.zip b/v2/rscg_examples_site/static/sources/TypedPaths.zip new file mode 100644 index 0000000000000000000000000000000000000000..4137ef77923ee32d7610c403a04965230dd94d21 GIT binary patch literal 980 zcmWIWW@Zs#U|`^2C|c7L^I_?Zg|IHIm=$zaTT6Frnr>8F0$?|jlo>$$Uy-*bwX9(5Oe8If+ z<_qPSj0^#AyExZ2#l#)D<>AK2z_5{tfk6SyE`1b>lZy+A^0Qil4h9`E5V1MT^IyPN z?#l(SW7)Twc?@hjdKNrB=$#`k;W_!->DLVE+Vtz>DxTB*}nVi?2huh z)lNC`?5EW;b1moBZzdgjnITx!p}se7{pko@ZN^Mv$LOh^ypdWDM9p5^`=8G*2o4KfZ`I%Fy2~ReEJ62twJufWk`k%0E ztg}vBtb5ky!P)ipilFh#wNJU;C2(@6F;AQ26K;8A&pv0n$zL8F;*@ak6tk>mC^_Pv@3bb*;oVx2_iDb$v*I(i>Z~5=aP+ zA1q3-J-%nkqANaoHyoLBDP#g0JOwZ?JOidSpoMTC31lHhx_+X5VqQv7YNlREMM;1+ zBa;XN?qmu#1?%GH?jfxh!8~>f;}h@ dhU5XW2Z|x60mI4$Qpy5^l0e&*0u?hb004M_Sx5i? literal 0 HcmV?d00001