Err.ChangeTracking.SourceGenerator
0.4.0
See the version list below for details.
dotnet add package Err.ChangeTracking.SourceGenerator --version 0.4.0
NuGet\Install-Package Err.ChangeTracking.SourceGenerator -Version 0.4.0
<PackageReference Include="Err.ChangeTracking.SourceGenerator" Version="0.4.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Err.ChangeTracking.SourceGenerator" Version="0.4.0" />
<PackageReference Include="Err.ChangeTracking.SourceGenerator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Err.ChangeTracking.SourceGenerator --version 0.4.0
#r "nuget: Err.ChangeTracking.SourceGenerator, 0.4.0"
#:package Err.ChangeTracking.SourceGenerator@0.4.0
#addin nuget:?package=Err.ChangeTracking.SourceGenerator&version=0.4.0
#tool nuget:?package=Err.ChangeTracking.SourceGenerator&version=0.4.0
Err.ChangeTracking Solution (Full Documentation)
A complete, high-performance, AOT-friendly solution to track changes on POCO models โ combining runtime efficiency and compile-time generation.
๐ Introduction
Managing changes on POCO models is a common but tedious problem. Manually tracking modifications leads to verbose code, maintenance headaches, and runtime inefficiency.
Err.ChangeTracking provides:
- A lightweight runtime library.
- A powerful Roslyn Source Generator to automate everything at compile time.
Result?
โก Lightning-fast, zero-reflection change tracking ready for Blazor, NativeAOT, Cloud, Web, and Mobile.
๐จ Problem Statement
โ
How to detect if a POCO model has been modified?
โ
How to rollback changes easily?
โ
How to track changes without relying on slow reflection or dynamic proxies?
Conventional solutions introduce runtime overhead and are not AOT-friendly.
๐ Manual Implementation Example (Using Only Err.ChangeTracking
Runtime)
using System;
using Err.ChangeTracking;
public partial class Person : ITrackable<Person>
{
private IChangeTracking<Person> _changeTracker;
public IChangeTracking<Person> GetChangeTracker() => _changeTracker ??= new ChangeTracking<Person>(this);
private string _firstName;
public partial string FirstName
{
get => _firstName;
set { _changeTracker?.RecordChange(nameof(FirstName), _firstName, value); _firstName = value; }
}
private int _age;
public partial int Age
{
get => _age;
set { _changeTracker?.RecordChange(nameof(Age), _age, value); _age = value; }
}
}
Explanation:
_changeTracker
monitors the original values.RecordChange
is called manually inside each setter.IsDirty
,Rollback
, andAcceptChanges
become available.
โ Powerful โ but โ very repetitive and error-prone for large models.
๐ค With Err.ChangeTracking.SourceGenerator (Recommended)
Instead of manually writing setters, just annotate your class:
[Trackable]
public partial class Person
{
public partial string FirstName { get; set; }
public partial int Age { get; set; }
}
The source generator will auto-generate the backing fields, tracking logic, and setter wrappers.
โ Keep your models clean, readable, and efficient.
โจ How the Generator Works
- Class must be marked as
[Trackable]
- Class must be
partial
- Public,
partial
properties are eligible - Attributes control behavior:
Attribute | Behavior |
---|---|
[TrackOnly] |
Track this property only (when using TrackingMode.OnlyMarked ) |
[NotTracked] |
Exclude this property from tracking |
[TrackCollection] |
Track changes inside List/Dictionary items |
TrackingMode.All |
(default) track all eligible properties |
TrackingMode.OnlyMarked |
Only track [TrackOnly] properties |
๐งช Examples From Unit Tests
Tracking simple properties
var person = new Person { FirstName = "Alice", Age = 30 }.AsTrackable();
person.FirstName = "Bob";
Assert.True(person.GetChangeTracker().IsDirty);
Assert.True(person.GetChangeTracker().HasChanged(x => x.FirstName));
Rollback a single property
person.GetChangeTracker().Rollback(x => x.FirstName);
Assert.Equal("Alice", person.FirstName);
Tracking collections
[Trackable]
public partial class Order
{
[TrackCollection]
public partial List<string> Items { get; set; }
}
var order = new Order { Items = new List<string>() }.AsTrackable();
order.Items.AsTrackable().Add("New Item");
Assert.True(order.GetChangeTracker().IsDirty);
TrackingMode OnlyMarked with [TrackOnly]
[Trackable(Mode = TrackingMode.OnlyMarked)]
public partial class Invoice
{
[TrackOnly]
public partial string InvoiceNumber { get; set; }
public partial string Comment { get; set; }
}
var invoice = new Invoice { InvoiceNumber = "INV001", Comment = "Test" }.AsTrackable();
invoice.InvoiceNumber = "INV002";
invoice.Comment = "Changed Comment";
Assert.True(invoice.GetChangeTracker().HasChanged(x => x.InvoiceNumber));
Assert.False(invoice.GetChangeTracker().HasChanged(x => x.Comment));
๐ Typical Use Cases
- Change tracking in CRUD applications
- Undo/Redo features
- Form validation and dirty detection
- Optimizing entity update operations
๐ฆ Requirements
IMPORTANT: This package uses C# 13 feature Patrial properties and requires either:
- .NET 9.0 or higher, OR
- .NET 8.0 with LangVersion set to "preview" in your project file
If you're using .NET 8.0, add the following to your project file:
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
! Without this configuration, the source generator will not work correctly.
๐ฆ Installation
dotnet add package Err.ChangeTracking
dotnet add package Err.ChangeTracking.SourceGenerator
๐ License
Licensed under the MIT License.
๐ฅ Related Projects
- Err.ChangeTracking โ Runtime library
- Err.ChangeTracking.SourceGenerator โ Roslyn code generator
๐ Contributions
Contributions are welcome!
Fork the repository, submit a PR, or open an issue to suggest improvements!
Built with โค๏ธ by ERRADIL
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.