diff --git a/README.md b/README.md
index 19e54beb8..d3304c8eb 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# RSCG - 286 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
+# RSCG - 287 Examples of Roslyn Source Code Generators / 16 created by Microsoft /
-The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 286 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 287 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-27 => 27 August 2026
+## Latest Update : 2026-08-28 => 28 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,30 @@ If you want to be notified each time I add a new RSCG example , please click htt
## Content
-Those are the 286 Roslyn Source Code Generators that I have tested you can see and download source code example.
+Those are the 287 Roslyn Source Code Generators that I have tested you can see and download source code example.
( including 16 from Microsoft )
+### 287. [TrimItEasy](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy) , in the [EnhancementClass](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementclass) category
+
+Generated on : 2026-08-28 => 28 August 2026
+
+
+ Expand
+
+
+
+Author: Phong Nguyen
+
+Package Description
+
+Nuget: [https://www.nuget.org/packages/TrimItEasy/](https://www.nuget.org/packages/TrimItEasy/)
+
+
+Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy)
+
+Source: [https://github.com/phongnguyend/TrimItEasy](https://github.com/phongnguyend/TrimItEasy)
+
+
+
### 286. [SatorImaging.TDoubles](https://ignatandrei.github.io/RSCG_Examples/v2/docs/SatorImaging.TDoubles) , in the [Tests](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#tests) category
Generated on : 2026-08-27 => 27 August 2026
diff --git a/later.md b/later.md
index db0f7aed3..5c92ff14f 100644
--- a/later.md
+++ b/later.md
@@ -1,6 +1,6 @@
# Just later
-## Latest Update : 2026-08-27 => 27 August 2026
+## Latest Update : 2026-08-28 => 28 August 2026
diff --git a/v2/.tours/TrimItEasy.tour b/v2/.tours/TrimItEasy.tour
new file mode 100644
index 000000000..d3e903fb1
--- /dev/null
+++ b/v2/.tours/TrimItEasy.tour
@@ -0,0 +1,30 @@
+
+{
+ "$schema": "https://aka.ms/codetour-schema",
+ "title": "TrimItEasy",
+ "steps":
+ [
+ {
+ "file": "rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj",
+ "description": "First, we add Nuget [TrimItEasy](https://www.nuget.org/packages/TrimItEasy/) in csproj ",
+ "pattern": "TrimItEasy"
+ }
+
+ ,{
+ "file": "rscg_examples/TrimItEasy/src/TrimDemo/Program.cs",
+ "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj ",
+ "pattern": "this is the code"
+ }
+
+
+ ,{
+ "file": "rscg_examples/TrimItEasy/src/TrimDemo/obj/GX/TrimItEasy.Generators/TrimItEasy.Generators.TrimmerSourceGenerator/PersonExtensions_FastTrimStrings.g.cs",
+ "description": "Generated File 1 from 1 : PersonExtensions_FastTrimStrings.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 8ed5de681..7a2489f21 100644
--- a/v2/Generator/all.csv
+++ b/v2/Generator/all.csv
@@ -285,3 +285,4 @@ Nr,Key,Source,Category
284,Pinecone.TypedPath, https://github.com/nickpinecone/typed-path,FilesToCode
285,PropertyResolvers, https://github.com/tombiddulph/PropertyResolvers,EnhancementProject
286,SatorImaging.TDoubles, https://github.com/sator-imaging/TDoubles,Tests
+287,TrimItEasy, https://github.com/phongnguyend/TrimItEasy,EnhancementClass
diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json
index 4e0c4b142..f5a56d8d8 100644
--- a/v2/RSCGExamplesData/GeneratorDataRec.json
+++ b/v2/RSCGExamplesData/GeneratorDataRec.json
@@ -1734,5 +1734,11 @@
"dtStart": "2026-08-27T00:00:00",
"show": true
}
+ ,{
+ "ID":"TrimItEasy",
+ "Category": 5,
+ "dtStart": "2026-08-28T00:00:00",
+ "show": true
+ }
]
\ No newline at end of file
diff --git a/v2/book/examples/TrimItEasy.html b/v2/book/examples/TrimItEasy.html
new file mode 100644
index 000000000..3094a5ec2
--- /dev/null
+++ b/v2/book/examples/TrimItEasy.html
@@ -0,0 +1,53 @@
+
+
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml
index ebec810a2..9cfa09947 100644
--- a/v2/book/pandocHTML.yaml
+++ b/v2/book/pandocHTML.yaml
@@ -300,6 +300,7 @@ input-files:
- examples/Pinecone.TypedPath.html
- examples/PropertyResolvers.html
- examples/SatorImaging.TDoubles.html
+- examples/TrimItEasy.html
# or you may use input-file: with a single value
# defaults:
diff --git a/v2/docFind.json b/v2/docFind.json
index 4f3c3ee43..15638d3e5 100644
--- a/v2/docFind.json
+++ b/v2/docFind.json
@@ -1714,5 +1714,11 @@
"category": "Tests",
"href": "/RSCG_Examples/v2/docs/SatorImaging.TDoubles/",
"body": "Incremental source generator for creating mock wrapper classes."
+ },
+ {
+ "title": "TrimItEasy",
+ "category": "EnhancementClass",
+ "href": "/RSCG_Examples/v2/docs/TrimItEasy/",
+ "body": "Package Description"
}
]
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/description.json b/v2/rscg_examples/TrimItEasy/description.json
new file mode 100644
index 000000000..e50e20f82
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/description.json
@@ -0,0 +1,22 @@
+{
+ "generator":{
+ "name":"TrimItEasy",
+ "nuget":[
+ "https://www.nuget.org/packages/TrimItEasy/"
+ ],
+ "link":"https://github.com/phongnguyend/TrimItEasy",
+ "author":"Phong Nguyen",
+ "source":"https://github.com/phongnguyend/TrimItEasy"
+ },
+ "data":{
+ "goodFor":["trimming eacg string from a class properties"],
+ "csprojDemo":"TrimDemo.csproj",
+ "csFiles":["Program.cs"],
+ "excludeDirectoryGenerated":[""],
+ "includeAdditionalFiles":[""]
+ },
+ "links":{
+ "blog":"",
+ "video":""
+ }
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/nuget.txt b/v2/rscg_examples/TrimItEasy/nuget.txt
new file mode 100644
index 000000000..882e74f60
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/nuget.txt
@@ -0,0 +1 @@
+Package Description
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/readme.txt b/v2/rscg_examples/TrimItEasy/readme.txt
new file mode 100644
index 000000000..4c39f2b43
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/readme.txt
@@ -0,0 +1,286 @@
+# TrimItEasy
+
+A simple and efficient .NET library for automatically trimming string properties in complex objects.
+
+## Installation
+
+Install the package from NuGet:
+
+```bash
+dotnet add package TrimItEasy
+```
+
+Or using the NuGet Package Manager in Visual Studio:
+```
+Install-Package TrimItEasy
+```
+
+## Usage
+
+### Basic Usage
+
+Simply call the `TrimStrings()` extension method on any complex object:
+
+```csharp
+using TrimItEasy;
+
+public class Person
+{
+ public string Name { get; set; }
+
+ public string Email { get; set; }
+
+ public Address HomeAddress { get; set; }
+}
+
+var person = new Person
+{
+ Name = " John Doe ",
+ Email = " john@example.com ",
+ HomeAddress = new Address
+ {
+ Street = " 123 Main St ",
+ City = " New York "
+ }
+};
+
+// Trim all string properties
+person.TrimStrings();
+```
+
+### Skip Trimming Specific Properties
+
+Use the `[NotTrimmed]` attribute to prevent trimming of specific properties:
+
+```csharp
+public class Address
+{
+ [NotTrimmed]
+ public string Street { get; set; } // This property will not be trimmed
+
+ public string City { get; set; } // This property will be trimmed
+}
+
+var address = new Address
+{
+ Street = " 123 Main St, Apt 4B ", // Will remain unchanged
+ City = " New York " // Will be trimmed to "New York"
+};
+
+address.TrimStrings();
+```
+
+### Recursive Trimming
+
+By default, the library recursively trims all string properties in nested objects up to a maximum depth of 64 levels. You can customize this behavior using `TrimmingOptions`:
+
+```csharp
+// Only trim top-level string properties (disable recursion)
+person.TrimStrings(new TrimmingOptions { Recursive = false });
+
+// Limit recursion to 2 levels of nested objects
+person.TrimStrings(new TrimmingOptions { MaxDepth = 2 });
+
+// Only trim the top-level object's string properties (no nested objects)
+person.TrimStrings(new TrimmingOptions { MaxDepth = 0 });
+```
+
+| Option | Type | Default | Description |
+|-------------|--------|---------|------------------------------------------------------------------------------------------------------|
+| `Recursive` | `bool` | `true` | Whether to trim strings in nested objects. When `false`, only top-level string properties are trimmed.|
+| `MaxDepth` | `int` | `64` | Maximum depth for recursive trimming. `0` trims only top-level properties, `1` includes one level of nested objects, and so on. |
+
+### Supported Types
+
+The library works with:
+- Complex objects with string properties
+- Collections (Lists, Arrays, etc.)
+- Nested objects
+- Properties marked with `[NotTrimmed]` will be skipped
+
+### Limitations
+
+The library will throw an `ArgumentException` if you try to use it on:
+- String types (use `string.Trim()` instead)
+- Primitive types
+- Enum types
+
+## Examples
+
+### Working with Collections
+
+```csharp
+public class Company
+{
+ public string Name { get; set; }
+
+ public List Employees { get; set; }
+}
+
+public class Employee
+{
+ public string Name { get; set; }
+
+ [NotTrimmed]
+ public string EmployeeId { get; set; }
+}
+
+var company = new Company
+{
+ Name = " Acme Corp ",
+ Employees = new List
+ {
+ new Employee { Name = " John Doe ", EmployeeId = " E001 " },
+ new Employee { Name = " Jane Smith ", EmployeeId = " E002 " }
+ }
+};
+
+company.TrimStrings();
+// Result:
+// - company.Name = "Acme Corp"
+// - company.Employees[0].Name = "John Doe"
+// - company.Employees[0].EmployeeId = " E001 " (not trimmed due to [NotTrimmed])
+```
+
+### Working with Nested Objects
+
+```csharp
+public class Order
+{
+ public string OrderNumber { get; set; }
+
+ public Customer Customer { get; set; }
+
+ public List Items { get; set; }
+}
+
+public class Customer
+{
+ public string Name { get; set; }
+
+ [NotTrimmed]
+ public string PhoneNumber { get; set; }
+}
+
+var order = new Order
+{
+ OrderNumber = " ORD-001 ",
+ Customer = new Customer
+ {
+ Name = " John Doe ",
+ PhoneNumber = " +1 (555) 123-4567 "
+ },
+ Items = new List
+ {
+ new OrderItem { Description = " Product A " }
+ }
+};
+
+order.TrimStrings();
+// All string properties will be trimmed except Customer.PhoneNumber
+```
+
+### Source Generator (Zero Reflection)
+
+For maximum performance, TrimItEasy includes a source generator that produces optimized trimming code at compile time � no reflection at runtime.
+
+#### Installation
+
+Install both the core library and the source generator package:
+
+```bash
+dotnet add package TrimItEasy
+dotnet add package TrimItEasy.Generators
+```
+
+Or using the NuGet Package Manager in Visual Studio:
+```
+Install-Package TrimItEasy
+Install-Package TrimItEasy.Generators
+```
+
+> **Note:** The `TrimItEasy.Generators` package must be referenced as an analyzer. If you are referencing the project directly, use:
+> ```xml
+> OutputItemType="Analyzer"
+> ReferenceOutputAssembly="false" />
+> ```
+
+#### Usage
+
+1. **Define a `static partial` extension method** that takes your target type as a `this` parameter and returns `void`.
+2. **Annotate it with `[GeneratedTrimming]`**.
+
+The source generator will implement the method body automatically.
+
+```csharp
+using TrimItEasy;
+
+public class Person
+{
+ public string Name { get; set; }
+ public string Email { get; set; }
+ public Address HomeAddress { get; set; }
+ public List Phones { get; set; }
+}
+
+public class Address
+{
+ public string Street { get; set; }
+ public string City { get; set; }
+}
+
+public class Phone
+{
+ public string Type { get; set; }
+ public string Number { get; set; }
+}
+
+// Define the partial method � the source generator fills in the implementation
+public static partial class PersonExtensions
+{
+ [GeneratedTrimming]
+ public static partial void FastTrimStrings(this Person person);
+
+ [GeneratedTrimming]
+ public static partial void FastTrimStringsWithOptions(this Person person, TrimmingOptions? options = null);
+}
+```
+
+Then simply call the generated method:
+
+```csharp
+var person = new Person
+{
+ Name = " John Doe ",
+ Email = " john@example.com ",
+ HomeAddress = new Address
+ {
+ Street = " 123 Main St ",
+ City = " New York "
+ },
+ Phones = new List
+ {
+ new Phone { Type = " Mobile ", Number = " 123-456-7890 " }
+ }
+};
+
+person.FastTrimStrings();
+// All string properties are trimmed, including nested objects and collections
+```
+
+#### How It Works
+
+- The source generator analyzes the target type's property graph at compile time.
+- It generates a dedicated trimming method that directly accesses each string property � no reflection involved.
+- Nested objects and collections (`List`, arrays, etc.) are handled recursively.
+- Properties marked with `[NotTrimmed]` are respected and skipped.
+- Circular references are detected and handled safely using a visited set.
+
+## Contributing
+
+Contributions are welcome! Please feel free to submit a Pull Request.
+
+## License
+
+This project is licensed under the MIT License - see the LICENSE file for details.
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx b/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx
new file mode 100644
index 000000000..1ce7224a4
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs
new file mode 100644
index 000000000..c61bf8e96
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Person.cs
@@ -0,0 +1,18 @@
+using TrimItEasy;
+
+namespace TrimDemo;
+
+public partial class Person
+{
+ public int Id { get; set; }
+
+ public string FirstName { get; set; } = string.Empty;
+ public string LastName { get; set; }= string.Empty;
+
+}
+
+public static partial class PersonExtensions
+{
+ [GeneratedTrimming]
+ public static partial void FastTrimStrings(this Person person);
+}
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs
new file mode 100644
index 000000000..f546179fc
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/Program.cs
@@ -0,0 +1,7 @@
+using TrimDemo;
+
+Person p = new();
+p.FirstName = " Andrei ";
+p.LastName = " Ignat ";
+p.FastTrimStrings();
+Console.WriteLine(p.FirstName + " " + p.LastName);
\ No newline at end of file
diff --git a/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj b/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.csproj
new file mode 100644
index 000000000..534ec57af
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/src/TrimDemo/TrimDemo.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/TrimItEasy/video.json b/v2/rscg_examples/TrimItEasy/video.json
new file mode 100644
index 000000000..f1bb23c9f
--- /dev/null
+++ b/v2/rscg_examples/TrimItEasy/video.json
@@ -0,0 +1,39 @@
+{
+ "scriptName": "TrimItEasy",
+ "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 TrimItEasy . trimming eacg string from a class properties ."},
+{"typeStep":"browser","arg":"https://www.nuget.org/packages/TrimItEasy/"},
+{"typeStep":"text","arg": "The whole example is here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy"},
+{"typeStep":"text","arg": "You can download the code from here"},
+{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/TrimItEasy#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 TrimItEasy into the csproj "},
+
+{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\TrimItEasy\\src\\TrimDemo\\TrimDemo.csproj"},
+
+{"typeStep":"text","arg": "And now I will show you an example of using TrimItEasy"},
+
+{"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":"TrimDemo.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/TrimItEasy#download-example-net--c-",
+SpeakTest=" "},
+{"typeStep":"waitseconds","arg":"30"},
+]
+}
diff --git a/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md b/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md
new file mode 100644
index 000000000..421735cfe
--- /dev/null
+++ b/v2/rscg_examples_site/docs/Authors/Phong_Nguyen.md
@@ -0,0 +1,7 @@
+# Author : Phong Nguyen
+
+Number RSCG: 1
+
+
+ 1 [TrimItEasy](/docs/TrimItEasy) [](https://www.nuget.org/packages/TrimItEasy/)  2026-08-28
+
diff --git a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
index 51f96ad18..1a7b9e32e 100644
--- a/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
+++ b/v2/rscg_examples_site/docs/Categories/EnhancementClass.md
@@ -1,6 +1,6 @@
EnhancementClass
-Number RSCG: 30
+Number RSCG: 31
1 [ApparatusAOT](/docs/ApparatusAOT) [](https://www.nuget.org/packages/Apparatus.AOT.Reflection/)  2023-04-16
@@ -61,4 +61,6 @@ Number RSCG: 30
29 [TelemetryLogging](/docs/TelemetryLogging) [](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)  2023-11-30
30 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
+
+ 31 [TrimItEasy](/docs/TrimItEasy) [](https://www.nuget.org/packages/TrimItEasy/)  2026-08-28
\ No newline at end of file
diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
index a5701dca1..b4bc072cb 100644
--- a/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
+++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveEnhancementClass.mdx
@@ -60,6 +60,8 @@
30 [ThisClass](/docs/ThisClass) [](https://www.nuget.org/packages/ThisClass/)  2024-04-19
+ 31 [TrimItEasy](/docs/TrimItEasy) [](https://www.nuget.org/packages/TrimItEasy/)  2026-08-28
+
### See category
[EnhancementClass](/docs/Categories/EnhancementClass)
diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md
new file mode 100644
index 000000000..314ae2f27
--- /dev/null
+++ b/v2/rscg_examples_site/docs/RSCG-Examples/TrimItEasy.md
@@ -0,0 +1,529 @@
+---
+sidebar_position: 2870
+title: 287 - TrimItEasy
+description: trimming eacg string from a class properties
+slug: /TrimItEasy
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import TOCInline from '@theme/TOCInline';
+import SameCategory from '../Categories/_PrimitiveEnhancementClass.mdx';
+
+# TrimItEasy by Phong Nguyen
+
+
+
+
+## NuGet / site data
+[](https://www.nuget.org/packages/TrimItEasy/)
+[](https://github.com/phongnguyend/TrimItEasy)
+
+
+## Details
+
+### Info
+:::info
+
+Name: **TrimItEasy**
+
+Package Description
+
+Author: Phong Nguyen
+
+NuGet:
+*https://www.nuget.org/packages/TrimItEasy/*
+
+
+You can find more details at https://github.com/phongnguyend/TrimItEasy
+
+Source: https://github.com/phongnguyend/TrimItEasy
+
+:::
+
+### Author
+:::note
+Phong Nguyen
+
+:::
+
+## Original Readme
+:::note
+
+### TrimItEasy
+
+A simple and efficient .NET library for automatically trimming string properties in complex objects.
+
+###### Installation
+
+Install the package from NuGet:
+
+```bash
+dotnet add package TrimItEasy
+```
+
+Or using the NuGet Package Manager in Visual Studio:
+```
+Install-Package TrimItEasy
+```
+
+###### Usage
+
+######### Basic Usage
+
+Simply call the `TrimStrings()` extension method on any complex object:
+
+```csharp
+using TrimItEasy;
+
+public class Person
+{
+ public string Name \{ get; set; }
+
+ public string Email \{ get; set; }
+
+ public Address HomeAddress \{ get; set; }
+}
+
+var person = new Person
+{
+ Name = " John Doe ",
+ Email = " john@example.com ",
+ HomeAddress = new Address
+ {
+ Street = " 123 Main St ",
+ City = " New York "
+ }
+};
+
+// Trim all string properties
+person.TrimStrings();
+```
+
+######### Skip Trimming Specific Properties
+
+Use the `[NotTrimmed]` attribute to prevent trimming of specific properties:
+
+```csharp
+public class Address
+{
+ [NotTrimmed]
+ public string Street \{ get; set; \} // This property will not be trimmed
+
+ public string City \{ get; set; \} // This property will be trimmed
+}
+
+var address = new Address
+{
+ Street = " 123 Main St, Apt 4B ", // Will remain unchanged
+ City = " New York " // Will be trimmed to "New York"
+};
+
+address.TrimStrings();
+```
+
+######### Recursive Trimming
+
+By default, the library recursively trims all string properties in nested objects up to a maximum depth of 64 levels. You can customize this behavior using `TrimmingOptions`:
+
+```csharp
+// Only trim top-level string properties (disable recursion)
+person.TrimStrings(new TrimmingOptions \{ Recursive = false });
+
+// Limit recursion to 2 levels of nested objects
+person.TrimStrings(new TrimmingOptions \{ MaxDepth = 2 });
+
+// Only trim the top-level object's string properties (no nested objects)
+person.TrimStrings(new TrimmingOptions \{ MaxDepth = 0 });
+```
+
+| Option | Type | Default | Description |
+|-------------|--------|---------|------------------------------------------------------------------------------------------------------|
+| `Recursive` | `bool` | `true` | Whether to trim strings in nested objects. When `false`, only top-level string properties are trimmed.|
+| `MaxDepth` | `int` | `64` | Maximum depth for recursive trimming. `0` trims only top-level properties, `1` includes one level of nested objects, and so on. |
+
+######### Supported Types
+
+The library works with:
+- Complex objects with string properties
+- Collections (Lists, Arrays, etc.)
+- Nested objects
+- Properties marked with `[NotTrimmed]` will be skipped
+
+######### Limitations
+
+The library will throw an `ArgumentException` if you try to use it on:
+- String types (use `string.Trim()` instead)
+- Primitive types
+- Enum types
+
+###### Examples
+
+######### Working with Collections
+
+```csharp
+public class Company
+{
+ public string Name \{ get; set; }
+
+ public List Employees \{ get; set; }
+}
+
+public class Employee
+{
+ public string Name \{ get; set; }
+
+ [NotTrimmed]
+ public string EmployeeId \{ get; set; }
+}
+
+var company = new Company
+{
+ Name = " Acme Corp ",
+ Employees = new List
+ {
+ new Employee \{ Name = " John Doe ", EmployeeId = " E001 " },
+ new Employee \{ Name = " Jane Smith ", EmployeeId = " E002 " }
+ }
+};
+
+company.TrimStrings();
+// Result:
+// - company.Name = "Acme Corp"
+// - company.Employees[0].Name = "John Doe"
+// - company.Employees[0].EmployeeId = " E001 " (not trimmed due to [NotTrimmed])
+```
+
+######### Working with Nested Objects
+
+```csharp
+public class Order
+{
+ public string OrderNumber \{ get; set; }
+
+ public Customer Customer \{ get; set; }
+
+ public List Items \{ get; set; }
+}
+
+public class Customer
+{
+ public string Name \{ get; set; }
+
+ [NotTrimmed]
+ public string PhoneNumber \{ get; set; }
+}
+
+var order = new Order
+{
+ OrderNumber = " ORD-001 ",
+ Customer = new Customer
+ {
+ Name = " John Doe ",
+ PhoneNumber = " +1 (555) 123-4567 "
+ },
+ Items = new List
+ {
+ new OrderItem \{ Description = " Product A " }
+ }
+};
+
+order.TrimStrings();
+// All string properties will be trimmed except Customer.PhoneNumber
+```
+
+######### Source Generator (Zero Reflection)
+
+For maximum performance, TrimItEasy includes a source generator that produces optimized trimming code at compile time � no reflection at runtime.
+
+########## Installation
+
+Install both the core library and the source generator package:
+
+```bash
+dotnet add package TrimItEasy
+dotnet add package TrimItEasy.Generators
+```
+
+Or using the NuGet Package Manager in Visual Studio:
+```
+Install-Package TrimItEasy
+Install-Package TrimItEasy.Generators
+```
+
+> **Note:** The `TrimItEasy.Generators` package must be referenced as an analyzer. If you are referencing the project directly, use:
+> ```xml
+> OutputItemType="Analyzer"
+> ReferenceOutputAssembly="false" />
+> ```
+
+########## Usage
+
+1. **Define a `static partial` extension method** that takes your target type as a `this` parameter and returns `void`.
+2. **Annotate it with `[GeneratedTrimming]`**.
+
+The source generator will implement the method body automatically.
+
+```csharp
+using TrimItEasy;
+
+public class Person
+{
+ public string Name \{ get; set; }
+ public string Email \{ get; set; }
+ public Address HomeAddress \{ get; set; }
+ public List Phones \{ get; set; }
+}
+
+public class Address
+{
+ public string Street \{ get; set; }
+ public string City \{ get; set; }
+}
+
+public class Phone
+{
+ public string Type \{ get; set; }
+ public string Number \{ get; set; }
+}
+
+// Define the partial method � the source generator fills in the implementation
+public static partial class PersonExtensions
+{
+ [GeneratedTrimming]
+ public static partial void FastTrimStrings(this Person person);
+
+ [GeneratedTrimming]
+ public static partial void FastTrimStringsWithOptions(this Person person, TrimmingOptions? options = null);
+}
+```
+
+Then simply call the generated method:
+
+```csharp
+var person = new Person
+{
+ Name = " John Doe ",
+ Email = " john@example.com ",
+ HomeAddress = new Address
+ {
+ Street = " 123 Main St ",
+ City = " New York "
+ },
+ Phones = new List
+ {
+ new Phone \{ Type = " Mobile ", Number = " 123-456-7890 " }
+ }
+};
+
+person.FastTrimStrings();
+// All string properties are trimmed, including nested objects and collections
+```
+
+########## How It Works
+
+- The source generator analyzes the target type's property graph at compile time.
+- It generates a dedicated trimming method that directly accesses each string property � no reflection involved.
+- Nested objects and collections (`List`, arrays, etc.) are handled recursively.
+- Properties marked with `[NotTrimmed]` are respected and skipped.
+- Circular references are detected and handled safely using a visited set.
+
+###### Contributing
+
+Contributions are welcome! Please feel free to submit a Pull Request.
+
+###### License
+
+This project is licensed under the MIT License - see the LICENSE file for details.
+
+:::
+
+### About
+:::note
+
+trimming eacg string from a class properties
+
+
+:::
+
+## How to use
+
+### Example (source csproj, source files)
+
+
+
+
+
+This is the CSharp Project that references **TrimItEasy**
+```xml showLineNumbers {11}
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ true
+ $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```
+
+
+
+
+
+ This is the use of **TrimItEasy** in *Program.cs*
+
+```csharp showLineNumbers
+using TrimDemo;
+
+Person p = new();
+p.FirstName = " Andrei ";
+p.LastName = " Ignat ";
+p.FastTrimStrings();
+Console.WriteLine(p.FirstName + " " + p.LastName);
+```
+
+
+
+
+### Generated Files
+
+Those are taken from $(BaseIntermediateOutputPath)\GX
+
+
+
+
+```csharp showLineNumbers
+//
+#nullable enable
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace TrimDemo;
+
+public static partial class PersonExtensions
+{
+ public static partial void FastTrimStrings(this global::TrimDemo.Person person)
+ {
+ var visited = new HashSet
+
+
+
+## Useful
+
+### Download Example (.NET C#)
+
+:::tip
+
+[Download Example project TrimItEasy ](/sources/TrimItEasy.zip)
+
+:::
+
+
+### Share TrimItEasy
+
+