Dhazel.Revertibles 1.1.0

dotnet add package Dhazel.Revertibles --version 1.1.0
                    
NuGet\Install-Package Dhazel.Revertibles -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Dhazel.Revertibles" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Dhazel.Revertibles" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Dhazel.Revertibles" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Dhazel.Revertibles --version 1.1.0
                    
#r "nuget: Dhazel.Revertibles, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Dhazel.Revertibles@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Dhazel.Revertibles&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Dhazel.Revertibles&version=1.1.0
                    
Install as a Cake Tool

Dhazel.Revertibles

.NET utilities for property change tracking: detect dirty state, revert to pristine values, and accept changes as the new baseline.

Projects

Project Description
Dhazel.Revertibles Core change-tracking API
Dhazel.Revertibles.Generators Source generator + analyzers for [RevertibleObject]
Dhazel.Revertibles.Mvvm MVVM integration (RevertibleValidator + CommunityToolkit.Mvvm)
Dhazel.TestHelpers Shared test helpers
Dhazel.Revertibles.Tests Unit tests for Revertibles
Dhazel.Revertibles.Generators.Tests Unit tests for the generator and analyzers
Dhazel.Revertibles.Mvvm.Tests Unit tests for Mvvm

Requirements

  • .NET 10

Install

dotnet add package Dhazel.Revertibles
dotnet add package Dhazel.Revertibles.Mvvm

Usage

All patterns share the same API:

Method Description
HasChanged() / HasChanged("Prop") Whether any (or a specific) tracked property differs from its pristine value
Revert() / Revert("Prop") Restore all (or a specific) tracked properties to pristine values
AcceptChanges() / AcceptChanges("Prop") Snapshot current values as the new pristine baseline

1. Attribute + Revertible.Track

Decorate properties with [Revertible], then track any instance:

using Dhazel.Revertibles;

public class Person
{
    [Revertible]
    public int Id { get; set; }

    [Revertible]
    public string? Name { get; set; }
}

var person = new Person { Id = 1, Name = "Ada" };
var revertible = Revertible.Track(person);

person.Name = "Grace";
revertible.HasChanged();           // true
revertible.HasChanged("Name");     // true

revertible.Revert("Name");
// person.Name == "Ada"

person.Name = "Grace";
revertible.AcceptChanges();
// "Grace" is now the pristine value

2. Inherit AbstractRevertible

When the type itself should be revertible:

using Dhazel.Revertibles;

public class Person : AbstractRevertible
{
    [Revertible]
    public int Id { get; set; }

    [Revertible]
    public string? Name { get; set; }
}

var person = new Person { Id = 1, Name = "Ada" };

person.Name = "Grace";
person.HasChanged();   // true
person.Revert();       // Name restored to "Ada"

3. Third-party / undecorated types

Track objects you cannot annotate (or choose not to) with WithProperties:

using Dhazel.Revertibles;

// No [Revertible] attributes on this type
public class ExternalDto
{
    public int Id { get; set; }
    public string? Name { get; set; }
}

var dto = new ExternalDto { Id = 1, Name = "Ada" };
var revertible = Revertible.Track(dto)
    .WithProperties(["Id", "Name"]);

dto.Name = "Grace";
revertible.HasChanged("Name");  // true
revertible.Revert();            // restored

4. MVVM with RevertibleValidator

Combine change tracking with CommunityToolkit.Mvvm source generators:

using CommunityToolkit.Mvvm.ComponentModel;
using Dhazel.Revertibles.Mvvm.ObservableValidators;
using Dhazel.Revertibles;

public partial class PersonViewModel : RevertibleValidator
{
    [ObservableProperty]
    [property: Revertible]
    private int _id;

    [ObservableProperty]
    [property: Revertible]
    private string? _name;
}

var vm = new PersonViewModel { Id = 1, Name = "Ada" };

vm.Name = "Grace";
vm.HasChanged();  // true
vm.Revert();      // Name restored to "Ada"

5. [RevertibleObject] — zero-boilerplate codegen

Skip the base class and manual wiring entirely. Decorate any partial class with [RevertibleObject], and mark the properties to track with [Revertible]. A source generator adds AcceptChanges, HasChanged, Revert, and WithProperties directly to your class:

Note: When using this attribute the Revertible instance is lazily loaded and change tracking will not begin until AcceptChanges is called. This can be done in the revertible objects constructor

using Dhazel.Revertibles;

[RevertibleObject]
public partial class Person
{
    [Revertible]
    public int Id { get; set; }

    [Revertible]
    public string? Name { get; set; }
}

var person = new Person { Id = 1, Name = "Ada" };
// AcceptChanges() runs automatically after construction by default

person.Name = "Grace";
person.HasChanged();   // true
person.Revert();       // Name restored to "Ada"

The class must be declared partial — an analyzer (REV001) flags this as a compile error if you forget. A second analyzer (REV002) warns if a [RevertibleObject] class has no [Revertible] properties, since that combination silently does nothing.

Deferring the initial snapshot

By default, the generated code snapshots pristine values the first time you call AcceptChanges, HasChanged, Revert, or WithProperties — which, left alone, happens automatically right after construction. If your class needs additional setup before its properties are safe to snapshot (e.g. a base class that finishes initializing after your constructor runs), set AcceptPristineValues = false and call AcceptChanges() yourself once setup is complete:

[RevertibleObject(AcceptPristineValues = false)]
public partial class PersonViewModel : ObservableValidator
{
    [Revertible]
    public int Id { get; set; }

    public PersonViewModel()
    {
        // ... setup that must happen before values are snapshotted ...
        AcceptChanges();
    }
}

Reference both packages/projects as needed:

  • Dhazel.Revertibles — core types
  • Dhazel.Revertibles.Mvvm — RevertibleValidator (depends on Revertibles and CommunityToolkit.Mvvm)

Build & test

dotnet build Dhazel.Revertibles.slnx
dotnet test Dhazel.Revertibles.slnx

Releasing

Versions come from git tags via MinVer (v1.0.0 → package 1.0.0).

  1. Ensure NUGET_USER is set as a GitHub Actions secret (nuget.org API key).
  2. Push an annotated tag:
git tag -a v1.0.0 -m "v1.0.0"
git push origin v1.0.0

The Release workflow runs tests, packs, and publishes to nuget.org.

Solution layout

root/
├── Dhazel.Revertibles/           # Core library
├── Dhazel.Revertibles/Generators # Roslyn Generators
├── Dhazel.Revertibles.Mvvm/      # MVVM helpers
├── Dhazel.TestHelpers/           # Test utilities
├── Dhazel.Revertibles.Tests/
├── Dhazel.Revertibles.Generators.Tests/
├── Dhazel.Revertibles.Mvvm.Tests/
└── Dhazel.Revertibles.slnx

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Dhazel.Revertibles:

Package Downloads
Dhazel.Revertibles.Mvvm

MVVM integration for Dhazel.Revertibles (RevertibleValidator + CommunityToolkit.Mvvm).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 449 8/11/2026
1.0.1-alpha.0.3 84 8/11/2026
1.0.0 252 7/18/2026