diff --git a/README.md b/README.md
index 9e7d88e52..24036abed 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# RSCG - 284 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
+# RSCG - 285 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
-The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 284 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 285 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-08-24 => 24 August 2026
+## Latest Update : 2026-08-26 => 26 August 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,32 @@ If you want to be notified each time I add a new RSCG example , please click htt
## Content
-Those are the 284 Roslyn Source Code Generators that I have tested you can see and download source code example.
+Those are the 285 Roslyn Source Code Generators that I have tested you can see and download source code example.
( including 16 from Microsoft )
+### 285. [PropertyResolvers](https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category
+
+Generated on : 2026-08-26 => 26 August 2026
+
+
+ Expand
+
+
+
+Author: Tom Biddulph
+
+A source generator that creates property resolver classes for types with
+ matching properties. Use assembly-level attributes to generate resolvers that can
+ retrieve property values from objects at runtime.
+
+Nuget: [https://www.nuget.org/packages/PropertyResolvers/](https://www.nuget.org/packages/PropertyResolvers/)
+
+
+Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers](https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers)
+
+Source: [https://github.com/tombiddulph/PropertyResolvers](https://github.com/tombiddulph/PropertyResolvers)
+
+
+
### 284. [Pinecone.TypedPath](https://ignatandrei.github.io/RSCG_Examples/v2/docs/Pinecone.TypedPath) , in the [FilesToCode](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#filestocode) category
Generated on : 2026-08-24 => 24 August 2026
diff --git a/later.md b/later.md
index d4ce7ef17..f93b018c1 100644
--- a/later.md
+++ b/later.md
@@ -1,6 +1,6 @@
# Just later
-## Latest Update : 2026-08-24 => 24 August 2026
+## Latest Update : 2026-08-26 => 26 August 2026
diff --git a/v2/.tours/PropertyResolvers.tour b/v2/.tours/PropertyResolvers.tour
new file mode 100644
index 000000000..7d171197f
--- /dev/null
+++ b/v2/.tours/PropertyResolvers.tour
@@ -0,0 +1,42 @@
+
+{
+ "$schema": "https://aka.ms/codetour-schema",
+ "title": "PropertyResolvers",
+ "steps":
+ [
+ {
+ "file": "rscg_examples/PropertyResolvers/src/PropSwitch/PropSwitch.csproj",
+ "description": "First, we add Nuget [PropertyResolvers](https://www.nuget.org/packages/PropertyResolvers/) in csproj ",
+ "pattern": "PropertyResolvers"
+ }
+
+ ,{
+ "file": "rscg_examples/PropertyResolvers/src/PropSwitch/Program.cs",
+ "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/PropertyResolvers/src/PropSwitch/PropSwitch.csproj ",
+ "pattern": "this is the code"
+ }
+
+ ,{
+ "file": "rscg_examples/PropertyResolvers/src/PropSwitch/Data.cs",
+ "description": "File Data.cs ",
+ "pattern": "this is the code"
+ }
+
+
+ ,{
+ "file": "rscg_examples/PropertyResolvers/src/PropSwitch/obj/GX/PropertyResolvers.Generators/PropertyResolvers.Generators.PropertyResolverGenerator/PropertyResolverRegistration.g.cs",
+ "description": "Generated File 2 from 2 : PropertyResolverRegistration.g.cs ",
+ "line": 1
+ }
+
+ ,{
+ "file": "rscg_examples/PropertyResolvers/src/PropSwitch/obj/GX/PropertyResolvers.Generators/PropertyResolvers.Generators.PropertyResolverGenerator/NameResolver.g.cs",
+ "description": "Generated File 1 from 2 : NameResolver.g.cs ",
+ "line": 1
+ }
+
+ ],
+
+ "ref": "main"
+
+}
\ No newline at end of file
diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv
index 8e2697ed9..6f6c4946f 100644
--- a/v2/Generator/all.csv
+++ b/v2/Generator/all.csv
@@ -283,3 +283,4 @@ Nr,Key,Source,Category
282,Clap.Net, https://github.com/simon-curtis/Clap.Net,CommandLine
283,IncrementalSourceGenerator.BuilderPattern, https://github.com/MartinBarrettNielsen11/Incremental-source-generator-builder-pattern,Builder
284,Pinecone.TypedPath, https://github.com/nickpinecone/typed-path,FilesToCode
+285,PropertyResolvers, https://github.com/tombiddulph/PropertyResolvers,EnhancementProject
diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json
index 27f7bd206..9fda4a89d 100644
--- a/v2/RSCGExamplesData/GeneratorDataRec.json
+++ b/v2/RSCGExamplesData/GeneratorDataRec.json
@@ -1721,5 +1721,12 @@
"Category": 8,
"dtStart": "2026-08-24T00:00:00",
"show": true
+ },
+ {
+ "ID": "PropertyResolvers",
+ "Category": 1,
+ "dtStart": "2026-08-26T00:00:00",
+ "show": true
}
+
]
\ No newline at end of file
diff --git a/v2/book/examples/PropertyResolvers.html b/v2/book/examples/PropertyResolvers.html
new file mode 100644
index 000000000..e811f26bb
--- /dev/null
+++ b/v2/book/examples/PropertyResolvers.html
@@ -0,0 +1,64 @@
+
+
RSCG nr 285 : PropertyResolvers
+
+Info
+Nuget : https://www.nuget.org/packages/PropertyResolvers/
+
+You can find more details at : https://github.com/tombiddulph/PropertyResolvers
+
+Author :Tom Biddulph
+
+Source: https://github.com/tombiddulph/PropertyResolvers
+
+About
+
+Generating code for switch for property in C#
+
+
+ How to use
+
+
+ Add reference to the PropertyResolvers in the csproj
+
+
+
+This was for me the starting code
+
+
+ I have coded the file Data.cs
+
+
+
+
+
+ I have coded the file Program.cs
+
+
+
+ And here are the generated files
+
+
+ The file generated is NameResolver.g.cs
+
+
+
+
+ The file generated is PropertyResolverRegistration.g.cs
+
+
+
+
+ You can download the code and this page as pdf from
+
+ https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers
+
+
+
+
+
+ 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 94d00675c..717346c51 100644
--- a/v2/book/list.html
+++ b/v2/book/list.html
@@ -17,7 +17,7 @@
-This is the list of 284 RSCG with examples =>
+This is the list of 285 RSCG with examples =>
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml
index 8bd080d2a..d6de7a8d7 100644
--- a/v2/book/pandocHTML.yaml
+++ b/v2/book/pandocHTML.yaml
@@ -298,6 +298,7 @@ input-files:
- examples/Clap.Net.html
- examples/IncrementalSourceGenerator.BuilderPattern.html
- examples/Pinecone.TypedPath.html
+- examples/PropertyResolvers.html
# or you may use input-file: with a single value
# defaults:
diff --git a/v2/docFind.json b/v2/docFind.json
index 4fea67f44..82e178172 100644
--- a/v2/docFind.json
+++ b/v2/docFind.json
@@ -1702,5 +1702,11 @@
"category": "FilesToCode",
"href": "/RSCG_Examples/v2/docs/Pinecone.TypedPath/",
"body": ".NET source generator for strongly typed file paths"
+ },
+ {
+ "title": "PropertyResolvers",
+ "category": "EnhancementProject",
+ "href": "/RSCG_Examples/v2/docs/PropertyResolvers/",
+ "body": "A source generator that creates property resolver classes for types with\n matching properties. Use assembly-level attributes to generate resolvers that can\n retrieve property values from objects at runtime."
}
]
\ No newline at end of file
diff --git a/v2/rscg_examples/PropertyResolvers/description.json b/v2/rscg_examples/PropertyResolvers/description.json
new file mode 100644
index 000000000..9c4951744
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/description.json
@@ -0,0 +1,22 @@
+{
+ "generator":{
+ "name":"PropertyResolvers",
+ "nuget":[
+ "https://www.nuget.org/packages/PropertyResolvers/"
+ ],
+ "link":"https://github.com/tombiddulph/PropertyResolvers",
+ "author":"Tom Biddulph",
+ "source":"https://github.com/tombiddulph/PropertyResolvers"
+ },
+ "data":{
+ "goodFor":["Generating code for switch for property in C#"],
+ "csprojDemo":"PropSwitch.csproj",
+ "csFiles":["Data.cs","Program.cs"],
+ "excludeDirectoryGenerated":[""],
+ "includeAdditionalFiles":[""]
+ },
+ "links":{
+ "blog":"",
+ "video":""
+ }
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/PropertyResolvers/nuget.txt b/v2/rscg_examples/PropertyResolvers/nuget.txt
new file mode 100644
index 000000000..2fe48aee5
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/nuget.txt
@@ -0,0 +1,3 @@
+A source generator that creates property resolver classes for types with
+ matching properties. Use assembly-level attributes to generate resolvers that can
+ retrieve property values from objects at runtime.
\ No newline at end of file
diff --git a/v2/rscg_examples/PropertyResolvers/readme.txt b/v2/rscg_examples/PropertyResolvers/readme.txt
new file mode 100644
index 000000000..6e3c5d36d
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/readme.txt
@@ -0,0 +1,130 @@
+# PropertyResolvers
+
+A C# source generator that creates type-safe property resolver classes. Instead of using reflection at runtime to extract property values from objects, PropertyResolvers generates compile-time switch expressions that efficiently resolve property values across multiple types.
+
+## Installation
+
+```bash
+dotnet add package PropertyResolvers
+```
+
+## Quick Start
+
+1. Add assembly-level attributes to specify which properties you want resolvers for:
+
+```csharp
+using PropertyResolvers.Attributes;
+
+[assembly: GeneratePropertyResolver("AccountId")]
+[assembly: GeneratePropertyResolver("TenantId")]
+```
+
+2. The generator automatically finds all types with matching properties and generates resolver classes:
+
+```csharp
+// Generated code (AccountIdResolver.g.cs)
+public static class AccountIdResolver
+{
+ public static string? GetAccountId(object? obj) => obj switch
+ {
+ global::MyApp.Order x => x.AccountId.ToString(),
+ global::MyApp.Customer x => x.AccountId.ToString(),
+ global::MyApp.Invoice x => x.AccountId.ToString(),
+ _ => null
+ };
+}
+```
+
+3. Use the generated resolvers in your code:
+
+```csharp
+var order = new Order { AccountId = "ACC-123" };
+var customer = new Customer { AccountId = "ACC-456" };
+var product = new Product { Name = "Widget" }; // No AccountId property
+
+var id1 = AccountIdResolver.GetAccountId(order); // "ACC-123"
+var id2 = AccountIdResolver.GetAccountId(customer); // "ACC-456"
+var id3 = AccountIdResolver.GetAccountId(product); // null
+```
+
+## Use Cases
+
+- **Multi-tenant applications**: Extract `TenantId` from any entity without reflection
+- **Audit logging**: Consistently retrieve identifier properties across different entity types
+- **Event sourcing**: Extract aggregate IDs from various event types
+- **API responses**: Normalize property access across different DTO types
+
+## Configuration Options
+
+### Basic Usage
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId")]
+```
+
+### Namespace Filtering
+
+Include only specific namespaces:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", IncludeNamespaces = new[] { "MyApp.Domain", "MyApp.Entities" })]
+```
+
+Exclude specific namespaces:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", ExcludeNamespaces = new[] { "System", "Microsoft" })]
+```
+
+### Multiple Resolvers
+
+You can generate resolvers for multiple properties:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", ExcludeNamespaces = new[] { "System", "Microsoft" })]
+[assembly: GeneratePropertyResolver("TenantId", ExcludeNamespaces = new[] { "System", "Microsoft" })]
+[assembly: GeneratePropertyResolver("EntityId", ExcludeNamespaces = new[] { "System", "Microsoft" })]
+```
+
+## Attribute Reference
+
+### `GeneratePropertyResolverAttribute`
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `propertyName` | `string` | **(Required)** The name of the property to generate a resolver for. Case-insensitive matching. |
+| `IncludeNamespaces` | `string[]?` | Only include types from these namespaces (prefix match). |
+| `ExcludeNamespaces` | `string[]?` | Exclude types from these namespaces (prefix match). |
+
+## Analyzer
+
+The package includes an analyzer that detects duplicate property resolver definitions:
+
+```csharp
+// PR001: Property resolver for 'AccountId' is already defined
+[assembly: GeneratePropertyResolver("AccountId")]
+[assembly: GeneratePropertyResolver("AccountId")] // Error: duplicate
+```
+
+Duplicate detection is case-insensitive, so `"AccountId"` and `"accountid"` are considered duplicates.
+
+## How It Works
+
+1. The generator scans all assembly-level `GeneratePropertyResolver` attributes
+2. For each attribute, it finds all classes and structs with a matching property name
+3. It generates a static resolver class with a switch expression that pattern-matches on the object type
+4. The generated code uses `global::` prefixes to avoid namespace conflicts
+
+## Generated Code Location
+
+The generated resolver classes are placed in a namespace matching your assembly name. For example, if your assembly is `MyApp`, the resolvers will be in the `MyApp` namespace.
+
+## Requirements
+
+- .NET Standard 2.0 compatible (works with .NET Framework 4.7.2+ and .NET Core 2.0+)
+- C# 9.0 or later (for switch expressions in generated code)
+- Visual Studio 2022 17.0+ or compatible IDE with Roslyn 4.0+ support
+
+## License
+
+MIT
diff --git a/v2/rscg_examples/PropertyResolvers/src/PropSwitch.slnx b/v2/rscg_examples/PropertyResolvers/src/PropSwitch.slnx
new file mode 100644
index 000000000..a8c390083
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/src/PropSwitch.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Data.cs b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Data.cs
new file mode 100644
index 000000000..d4498cc9d
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Data.cs
@@ -0,0 +1,16 @@
+using PropertyResolvers.Attributes;
+[assembly: GeneratePropertyResolver("Name",IncludeNamespaces = ["PropSwitch"])]
+
+namespace PropSwitch;
+
+public class Person
+{
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+}
+
+public class College
+{
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+}
diff --git a/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Program.cs b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Program.cs
new file mode 100644
index 000000000..0bea597da
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/Program.cs
@@ -0,0 +1,7 @@
+
+using PropSwitch;
+
+Person p=new() { Id = 1, Name = "Andrei" };
+College c = new() { Id = 1, Name = "Mathematics" };
+Console.WriteLine(NameResolver.GetName(p));
+Console.WriteLine(NameResolver.GetName(c));
\ No newline at end of file
diff --git a/v2/rscg_examples/PropertyResolvers/src/PropSwitch/PropSwitch.csproj b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/PropSwitch.csproj
new file mode 100644
index 000000000..fc21720a0
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/src/PropSwitch/PropSwitch.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
diff --git a/v2/rscg_examples/PropertyResolvers/video.json b/v2/rscg_examples/PropertyResolvers/video.json
new file mode 100644
index 000000000..70afc08f5
--- /dev/null
+++ b/v2/rscg_examples/PropertyResolvers/video.json
@@ -0,0 +1,39 @@
+{
+ "scriptName": "PropertyResolvers",
+ "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 PropertyResolvers . Generating code for switch for property in C# ."},
+{"typeStep":"browser","arg":"https://www.nuget.org/packages/PropertyResolvers/"},
+{"typeStep":"text","arg": "The whole example is here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers"},
+{"typeStep":"text","arg": "You can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers#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 PropertyResolvers into the csproj "},
+
+{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\PropertyResolvers\\src\\PropSwitch\\PropSwitch.csproj"},
+
+{"typeStep":"text","arg": "And now I will show you an example of using PropertyResolvers"},
+
+{"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":"PropSwitch.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/PropertyResolvers#download-example-net--c-",
+SpeakTest=" "},
+{"typeStep":"waitseconds","arg":"30"},
+]
+}
diff --git a/v2/rscg_examples_site/docs/Authors/Tom_Biddulph.md b/v2/rscg_examples_site/docs/Authors/Tom_Biddulph.md
new file mode 100644
index 000000000..98b2c2cf3
--- /dev/null
+++ b/v2/rscg_examples_site/docs/Authors/Tom_Biddulph.md
@@ -0,0 +1,7 @@
+# Author : Tom Biddulph
+
+Number RSCG: 1
+
+
+ 1 [PropertyResolvers](/docs/PropertyResolvers) [](https://www.nuget.org/packages/PropertyResolvers/)  2026-08-26
+
diff --git a/v2/rscg_examples_site/docs/Categories/EnhancementProject.md b/v2/rscg_examples_site/docs/Categories/EnhancementProject.md
index 2b7bb5f1a..964c5b50d 100644
--- a/v2/rscg_examples_site/docs/Categories/EnhancementProject.md
+++ b/v2/rscg_examples_site/docs/Categories/EnhancementProject.md
@@ -1,6 +1,6 @@
EnhancementProject
-Number RSCG: 22
+Number RSCG: 23
1 [AssemblyMetadata](/docs/AssemblyMetadata) [](https://www.nuget.org/packages/AssemblyMetadata/)  2026-04-02
@@ -26,23 +26,25 @@ Number RSCG: 22
12 [PlantUmlClassDiagramGenerator](/docs/PlantUmlClassDiagramGenerator) [](https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.SourceGenerator/)[](https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.Attributes/)  2024-02-20
- 13 [RSCG_AMS](/docs/RSCG_AMS) [](https://www.nuget.org/packages/RSCG_AMS/)  2023-04-16
+ 13 [PropertyResolvers](/docs/PropertyResolvers) [](https://www.nuget.org/packages/PropertyResolvers/)  2026-08-26
- 14 [RSCG_ExportDiagram](/docs/RSCG_ExportDiagram) [](https://github.com/ignatandrei/RSCG_ExportDiagram)  2024-08-01
+ 14 [RSCG_AMS](/docs/RSCG_AMS) [](https://www.nuget.org/packages/RSCG_AMS/)  2023-04-16
- 15 [RSCG_FunctionsWithDI](/docs/RSCG_FunctionsWithDI) [](https://www.nuget.org/packages/RSCG_FunctionsWithDI/)  2023-04-16
+ 15 [RSCG_ExportDiagram](/docs/RSCG_ExportDiagram) [](https://github.com/ignatandrei/RSCG_ExportDiagram)  2024-08-01
- 16 [RSCG_NameGenerator](/docs/RSCG_NameGenerator) [](https://www.nuget.org/packages/RSCG_NameGenerator/)  2024-08-25
+ 16 [RSCG_FunctionsWithDI](/docs/RSCG_FunctionsWithDI) [](https://www.nuget.org/packages/RSCG_FunctionsWithDI/)  2023-04-16
- 17 [RSCG_TimeBombComment](/docs/RSCG_TimeBombComment) [](https://www.nuget.org/packages/RSCG_TimeBombComment/)  2023-04-16
+ 17 [RSCG_NameGenerator](/docs/RSCG_NameGenerator) [](https://www.nuget.org/packages/RSCG_NameGenerator/)  2024-08-25
- 18 [RSCG_Wait](/docs/RSCG_Wait) [](https://www.nuget.org/packages/RSCG_WaitAndOptions/)  2024-02-21
+ 18 [RSCG_TimeBombComment](/docs/RSCG_TimeBombComment) [](https://www.nuget.org/packages/RSCG_TimeBombComment/)  2023-04-16
- 19 [ShadowWriterProjectInfo](/docs/ShadowWriterProjectInfo) [](https://www.nuget.org/packages/ShadowWriter/)  2025-07-27
+ 19 [RSCG_Wait](/docs/RSCG_Wait) [](https://www.nuget.org/packages/RSCG_WaitAndOptions/)  2024-02-21
- 20 [ThisAssembly](/docs/ThisAssembly) [](https://www.nuget.org/packages/ThisAssembly)  2023-04-16
+ 20 [ShadowWriterProjectInfo](/docs/ShadowWriterProjectInfo) [](https://www.nuget.org/packages/ShadowWriter/)  2025-07-27
- 21 [ThisAssembly.Constants](/docs/ThisAssembly.Constants) [](https://www.nuget.org/packages/ThisAssembly.Constants/)  2024-07-18
+ 21 [ThisAssembly](/docs/ThisAssembly) [](https://www.nuget.org/packages/ThisAssembly)  2023-04-16
- 22 [ThisAssembly.Metadata](/docs/ThisAssembly.Metadata) [](https://www.nuget.org/packages/ThisAssembly.Metadata/)  2024-07-20
+ 22 [ThisAssembly.Constants](/docs/ThisAssembly.Constants) [](https://www.nuget.org/packages/ThisAssembly.Constants/)  2024-07-18
+
+ 23 [ThisAssembly.Metadata](/docs/ThisAssembly.Metadata) [](https://www.nuget.org/packages/ThisAssembly.Metadata/)  2024-07-20
\ No newline at end of file
diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementProject.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementProject.mdx
index 8622833f9..479c770e4 100644
--- a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementProject.mdx
+++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementProject.mdx
@@ -24,25 +24,27 @@
12 [PlantUmlClassDiagramGenerator](/docs/PlantUmlClassDiagramGenerator) [](https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.SourceGenerator/)[](https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.Attributes/)  2024-02-20
- 13 [RSCG_AMS](/docs/RSCG_AMS) [](https://www.nuget.org/packages/RSCG_AMS/)  2023-04-16
+ 13 [PropertyResolvers](/docs/PropertyResolvers) [](https://www.nuget.org/packages/PropertyResolvers/)  2026-08-26
- 14 [RSCG_ExportDiagram](/docs/RSCG_ExportDiagram) [](https://github.com/ignatandrei/RSCG_ExportDiagram)  2024-08-01
+ 14 [RSCG_AMS](/docs/RSCG_AMS) [](https://www.nuget.org/packages/RSCG_AMS/)  2023-04-16
- 15 [RSCG_FunctionsWithDI](/docs/RSCG_FunctionsWithDI) [](https://www.nuget.org/packages/RSCG_FunctionsWithDI/)  2023-04-16
+ 15 [RSCG_ExportDiagram](/docs/RSCG_ExportDiagram) [](https://github.com/ignatandrei/RSCG_ExportDiagram)  2024-08-01
- 16 [RSCG_NameGenerator](/docs/RSCG_NameGenerator) [](https://www.nuget.org/packages/RSCG_NameGenerator/)  2024-08-25
+ 16 [RSCG_FunctionsWithDI](/docs/RSCG_FunctionsWithDI) [](https://www.nuget.org/packages/RSCG_FunctionsWithDI/)  2023-04-16
- 17 [RSCG_TimeBombComment](/docs/RSCG_TimeBombComment) [](https://www.nuget.org/packages/RSCG_TimeBombComment/)  2023-04-16
+ 17 [RSCG_NameGenerator](/docs/RSCG_NameGenerator) [](https://www.nuget.org/packages/RSCG_NameGenerator/)  2024-08-25
- 18 [RSCG_Wait](/docs/RSCG_Wait) [](https://www.nuget.org/packages/RSCG_WaitAndOptions/)  2024-02-21
+ 18 [RSCG_TimeBombComment](/docs/RSCG_TimeBombComment) [](https://www.nuget.org/packages/RSCG_TimeBombComment/)  2023-04-16
- 19 [ShadowWriterProjectInfo](/docs/ShadowWriterProjectInfo) [](https://www.nuget.org/packages/ShadowWriter/)  2025-07-27
+ 19 [RSCG_Wait](/docs/RSCG_Wait) [](https://www.nuget.org/packages/RSCG_WaitAndOptions/)  2024-02-21
- 20 [ThisAssembly](/docs/ThisAssembly) [](https://www.nuget.org/packages/ThisAssembly)  2023-04-16
+ 20 [ShadowWriterProjectInfo](/docs/ShadowWriterProjectInfo) [](https://www.nuget.org/packages/ShadowWriter/)  2025-07-27
- 21 [ThisAssembly.Constants](/docs/ThisAssembly.Constants) [](https://www.nuget.org/packages/ThisAssembly.Constants/)  2024-07-18
+ 21 [ThisAssembly](/docs/ThisAssembly) [](https://www.nuget.org/packages/ThisAssembly)  2023-04-16
- 22 [ThisAssembly.Metadata](/docs/ThisAssembly.Metadata) [](https://www.nuget.org/packages/ThisAssembly.Metadata/)  2024-07-20
+ 22 [ThisAssembly.Constants](/docs/ThisAssembly.Constants) [](https://www.nuget.org/packages/ThisAssembly.Constants/)  2024-07-18
+
+ 23 [ThisAssembly.Metadata](/docs/ThisAssembly.Metadata) [](https://www.nuget.org/packages/ThisAssembly.Metadata/)  2024-07-20
### See category
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/PropertyResolvers.md b/v2/rscg_examples_site/docs/RSCG-Examples/PropertyResolvers.md
new file mode 100644
index 000000000..4caa06677
--- /dev/null
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/PropertyResolvers.md
@@ -0,0 +1,350 @@
+---
+sidebar_position: 2850
+title: 285 - PropertyResolvers
+description: Generating code for switch for property in C#
+slug: /PropertyResolvers
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import TOCInline from '@theme/TOCInline';
+import SameCategory from '../Categories/_PrimitiveEnhancementProject.mdx';
+
+# PropertyResolvers by Tom Biddulph
+
+
+
+
+## NuGet / site data
+[](https://www.nuget.org/packages/PropertyResolvers/)
+[](https://github.com/tombiddulph/PropertyResolvers)
+
+
+## Details
+
+### Info
+:::info
+
+Name: **PropertyResolvers**
+
+A source generator that creates property resolver classes for types with
+ matching properties. Use assembly-level attributes to generate resolvers that can
+ retrieve property values from objects at runtime.
+
+Author: Tom Biddulph
+
+NuGet:
+*https://www.nuget.org/packages/PropertyResolvers/*
+
+
+You can find more details at https://github.com/tombiddulph/PropertyResolvers
+
+Source: https://github.com/tombiddulph/PropertyResolvers
+
+:::
+
+### Author
+:::note
+Tom Biddulph
+
+:::
+
+## Original Readme
+:::note
+
+### PropertyResolvers
+
+A C# source generator that creates type-safe property resolver classes. Instead of using reflection at runtime to extract property values from objects, PropertyResolvers generates compile-time switch expressions that efficiently resolve property values across multiple types.
+
+###### Installation
+
+```bash
+dotnet add package PropertyResolvers
+```
+
+###### Quick Start
+
+1. Add assembly-level attributes to specify which properties you want resolvers for:
+
+```csharp
+using PropertyResolvers.Attributes;
+
+[assembly: GeneratePropertyResolver("AccountId")]
+[assembly: GeneratePropertyResolver("TenantId")]
+```
+
+2. The generator automatically finds all types with matching properties and generates resolver classes:
+
+```csharp
+// Generated code (AccountIdResolver.g.cs)
+public static class AccountIdResolver
+{
+ public static string? GetAccountId(object? obj) => obj switch
+ {
+ global::MyApp.Order x => x.AccountId.ToString(),
+ global::MyApp.Customer x => x.AccountId.ToString(),
+ global::MyApp.Invoice x => x.AccountId.ToString(),
+ _ => null
+ };
+}
+```
+
+3. Use the generated resolvers in your code:
+
+```csharp
+var order = new Order \{ AccountId = "ACC-123" };
+var customer = new Customer \{ AccountId = "ACC-456" };
+var product = new Product \{ Name = "Widget" }; // No AccountId property
+
+var id1 = AccountIdResolver.GetAccountId(order); // "ACC-123"
+var id2 = AccountIdResolver.GetAccountId(customer); // "ACC-456"
+var id3 = AccountIdResolver.GetAccountId(product); // null
+```
+
+###### Use Cases
+
+- **Multi-tenant applications**: Extract `TenantId` from any entity without reflection
+- **Audit logging**: Consistently retrieve identifier properties across different entity types
+- **Event sourcing**: Extract aggregate IDs from various event types
+- **API responses**: Normalize property access across different DTO types
+
+###### Configuration Options
+
+######### Basic Usage
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId")]
+```
+
+######### Namespace Filtering
+
+Include only specific namespaces:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", IncludeNamespaces = new[] \{ "MyApp.Domain", "MyApp.Entities" })]
+```
+
+Exclude specific namespaces:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", ExcludeNamespaces = new[] \{ "System", "Microsoft" })]
+```
+
+######### Multiple Resolvers
+
+You can generate resolvers for multiple properties:
+
+```csharp
+[assembly: GeneratePropertyResolver("AccountId", ExcludeNamespaces = new[] \{ "System", "Microsoft" })]
+[assembly: GeneratePropertyResolver("TenantId", ExcludeNamespaces = new[] \{ "System", "Microsoft" })]
+[assembly: GeneratePropertyResolver("EntityId", ExcludeNamespaces = new[] \{ "System", "Microsoft" })]
+```
+
+###### Attribute Reference
+
+######### `GeneratePropertyResolverAttribute`
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `propertyName` | `string` | **(Required)** The name of the property to generate a resolver for. Case-insensitive matching. |
+| `IncludeNamespaces` | `string[]?` | Only include types from these namespaces (prefix match). |
+| `ExcludeNamespaces` | `string[]?` | Exclude types from these namespaces (prefix match). |
+
+###### Analyzer
+
+The package includes an analyzer that detects duplicate property resolver definitions:
+
+```csharp
+// PR001: Property resolver for 'AccountId' is already defined
+[assembly: GeneratePropertyResolver("AccountId")]
+[assembly: GeneratePropertyResolver("AccountId")] // Error: duplicate
+```
+
+Duplicate detection is case-insensitive, so `"AccountId"` and `"accountid"` are considered duplicates.
+
+###### How It Works
+
+1. The generator scans all assembly-level `GeneratePropertyResolver` attributes
+2. For each attribute, it finds all classes and structs with a matching property name
+3. It generates a static resolver class with a switch expression that pattern-matches on the object type
+4. The generated code uses `global::` prefixes to avoid namespace conflicts
+
+###### Generated Code Location
+
+The generated resolver classes are placed in a namespace matching your assembly name. For example, if your assembly is `MyApp`, the resolvers will be in the `MyApp` namespace.
+
+###### Requirements
+
+- .NET Standard 2.0 compatible (works with .NET Framework 4.7.2+ and .NET Core 2.0+)
+- C# 9.0 or later (for switch expressions in generated code)
+- Visual Studio 2022 17.0+ or compatible IDE with Roslyn 4.0+ support
+
+###### License
+
+MIT
+
+
+:::
+
+### About
+:::note
+
+Generating code for switch for property in C#
+
+
+:::
+
+## How to use
+
+### Example (source csproj, source files)
+
+
+
+
+
+This is the CSharp Project that references **PropertyResolvers**
+```xml showLineNumbers {11}
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```
+
+
+
+
+
+ This is the use of **PropertyResolvers** in *Data.cs*
+
+```csharp showLineNumbers
+using PropertyResolvers.Attributes;
+[assembly: GeneratePropertyResolver("Name",IncludeNamespaces = ["PropSwitch"])]
+
+namespace PropSwitch;
+
+public class Person
+{
+ public int Id \{ get; set; }
+ public string Name \{ get; set; \} = string.Empty;
+}
+
+public class College
+{
+ public int Id \{ get; set; }
+ public string Name \{ get; set; \} = string.Empty;
+}
+
+```
+
+
+
+
+ This is the use of **PropertyResolvers** in *Program.cs*
+
+```csharp showLineNumbers
+
+using PropSwitch;
+
+Person p=new() \{ Id = 1, Name = "Andrei" };
+College c = new() \{ Id = 1, Name = "Mathematics" };
+Console.WriteLine(NameResolver.GetName(p));
+Console.WriteLine(NameResolver.GetName(c));
+```
+
+
+
+
+### Generated Files
+
+Those are taken from $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```csharp showLineNumbers
+//
+#nullable enable
+
+namespace PropSwitch;
+
+public static class NameResolver
+{
+ public static string? GetName(object? obj) => obj switch
+ {
+ global::PropSwitch.Person x => x.Name.ToString(),
+ global::PropSwitch.College x => x.Name.ToString(),
+ _ => null
+ };
+
+}
+
+```
+
+
+
+
+```csharp showLineNumbers
+//
+#nullable enable
+
+using System.Runtime.CompilerServices;
+
+namespace PropSwitch;
+
+[CompilerGenerated]
+internal static class PropertyResolverModuleInitializer
+{
+ [ModuleInitializer]
+ internal static void Initialize()
+ {
+ global::PropertyResolvers.Attributes.PropertyResolverRegistry.Register("Name", global::PropSwitch.NameResolver.GetName);
+ }
+}
+
+```
+
+
+
+
+## Useful
+
+### Download Example (.NET C#)
+
+:::tip
+
+[Download Example project PropertyResolvers ](/sources/PropertyResolvers.zip)
+
+:::
+
+
+### Share PropertyResolvers
+
+
+
+https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers
+
+
+
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md
index 25fa71b09..84a4a91ce 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: 284 RSCG list by category
-description: 284 RSCG list by category
+title: 285 RSCG list by category
+description: 285 RSCG list by category
slug: /rscg-examples
---
@@ -735,7 +735,7 @@ import DocCardList from '@theme/DocCardList';
## EnhancementProject
- Expand EnhancementProject =>examples:22
+ Expand EnhancementProject =>examples:23
@@ -846,6 +846,11 @@ import DocCardList from '@theme/DocCardList';
[Bennewitz.Ninja.AutoVersioning](/docs/Bennewitz.Ninja.AutoVersioning)
+
+
+
+[PropertyResolvers](/docs/PropertyResolvers)
+
@@ -2045,6 +2050,8 @@ flowchart LR;
EnhancementProject--> Bennewitz.Ninja.AutoVersioning((Bennewitz.Ninja.AutoVersioning))
+ EnhancementProject--> PropertyResolvers((PropertyResolvers))
+
EntityFramework--> EntityLengths.Generator((EntityLengths.Generator))
EntityFramework--> Atulin.AutoDbSet((Atulin.AutoDbSet))
diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md
index 1b0054adc..1a11b36bc 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 284 Roslyn Source Code Generator (RSCG)
+of 285 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 675c97c98..1ad98a1b0 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';
-## 284 RSCG with examples in descending chronological order
+## 285 RSCG with examples in descending chronological order
-This is the list of 284 ( 16 from Microsoft) RSCG with examples
+This is the list of 285 ( 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 284 ( 16 from Microsoft) RSCG with examples
| No | Name | Date | Category |
| --------- | ----- | ---- | -------- |
+|285| [PropertyResolvers by Tom Biddulph ](/docs/PropertyResolvers)|2026-08-26 => 26 August 2026 | [EnhancementProject](/docs/Categories/EnhancementProject) |
|284| [Pinecone.TypedPath by Nick Pinecone ](/docs/Pinecone.TypedPath)|2026-08-24 => 24 August 2026 | [FilesToCode](/docs/Categories/FilesToCode) |
|283| [IncrementalSourceGenerator.BuilderPattern by Martin Barrett Nielsen ](/docs/IncrementalSourceGenerator.BuilderPattern)|2026-08-23 => 23 August 2026 | [Builder](/docs/Categories/Builder) |
|282| [Clap.Net by Simon Curtis ](/docs/Clap.Net)|2026-08-22 => 22 August 2026 | [CommandLine](/docs/Categories/CommandLine) |
diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js
index 747ef6416..e0f5467ce 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: '284 Examples (16 from MSFT)',
+title: '285 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 a6c7c3c18..47748093e 100644
--- a/v2/rscg_examples_site/static/exports/RSCG.json
+++ b/v2/rscg_examples_site/static/exports/RSCG.json
@@ -2273,6 +2273,14 @@
"Source": "https://github.com/nickpinecone/typed-path",
"Category": "FilesToCode",
"AddedOn": "2026-08-24T00:00:00"
+ },
+ {
+ "Name": "PropertyResolvers",
+ "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyResolvers",
+ "NuGet": "https://www.nuget.org/packages/PropertyResolvers/",
+ "Source": "https://github.com/tombiddulph/PropertyResolvers",
+ "Category": "EnhancementProject",
+ "AddedOn": "2026-08-26T00:00:00"
}
]
}
\ No newline at end of file
diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx
index 78cf324a3..4db423cb9 100644
Binary files a/v2/rscg_examples_site/static/exports/RSCG.xlsx and b/v2/rscg_examples_site/static/exports/RSCG.xlsx differ
diff --git a/v2/rscg_examples_site/static/sources/PropertyResolvers.zip b/v2/rscg_examples_site/static/sources/PropertyResolvers.zip
new file mode 100644
index 000000000..d90e40808
Binary files /dev/null and b/v2/rscg_examples_site/static/sources/PropertyResolvers.zip differ