ItCompiles.Data.Tracked 0.1.0-preview

Prefix Reserved
This is a prerelease version of ItCompiles.Data.Tracked.
dotnet add package ItCompiles.Data.Tracked --version 0.1.0-preview
                    
NuGet\Install-Package ItCompiles.Data.Tracked -Version 0.1.0-preview
                    
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="ItCompiles.Data.Tracked" Version="0.1.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ItCompiles.Data.Tracked" Version="0.1.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="ItCompiles.Data.Tracked" />
                    
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 ItCompiles.Data.Tracked --version 0.1.0-preview
                    
#r "nuget: ItCompiles.Data.Tracked, 0.1.0-preview"
                    
#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 ItCompiles.Data.Tracked@0.1.0-preview
                    
#: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=ItCompiles.Data.Tracked&version=0.1.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=ItCompiles.Data.Tracked&version=0.1.0-preview&prerelease
                    
Install as a Cake Tool

A Lightweight change tracking library for .NET objects and DTOs.

ItCompiles.Data.ChangeTracking allows you to edit complex object graphs without modifying the original data until you're ready. It supports nested objects, collections, commit/rollback, and lazy initialization while remaining fast enough for UI frameworks like Blazor.

Why?

Many applications need an "edit mode" where users can make changes before saving.

Instead of copying entire objects or manually tracking every field, this library wraps your existing DTOs and tracks modifications seperately

The original object is never modified until Commit() is called.

Features

  • Track simple properties
  • Track nested objects
  • Track collections
  • Commit or rollback changes
  • Lazy object graph creation
  • Reflection metadata caching
  • Preserve original object references
  • Designed for DTO editing

Usage/Examples

Create a tracked object.

var tracked = TrackedBuilder.Build(product);

Access a property (Edit Value).

tracked
    .Property(x => x.Name)
    .Value;

Access a property (Raw DTO).

tracked.Value

Edit a property.

tracked
    .Property(x => x.Name)
    .SetValue("New Name");

Check if anything changed.

if (tracked.IsChanged)
{
    ...
}

Commit changes.

tracked.Commit();

Rollback changes.

tracked.Rollback();

Tracking Nested Objects

Nested objects are tracked automatically.

tracked
    .Object(x => x.Customer)
    .Property(x => x.Name)
    .SetValue("John");

Changes propagate to the parent.

tracked.IsChanged

returns

true

Tracking Collections

Collections support editing without modifying the original collection.

var tags =
    tracked.Collection(x => x.Tags);

Replace the collection.

tags.SetCollection(newTags);

Add items.

tags.Add(tag);

Remove items.

tags.Remove(tag);

Clear.

tags.Clear();

Access tracked items.

foreach (var item in tags.Items)
{
    item.Property(x => x.Name).SetValue("Updated");
}

Commit

Nothing is written back to the original object until Commit.

tracked.Commit();

Property values are copied back to the original DTO.

Nested objects are committed recursively.

Collections are committed recursively.


Rollback

Discard every pending edit.

tracked.Rollback();

All edited values return to their original state.


Lazy Initialization

Objects and collections are created only when accessed.

This keeps startup costs low for large object graphs.

For example:

tracked.Property(x => x.Name)

does not initialize every collection on the object.

Collections are initialized only when requested.

tracked.Collection(x => x.Tags)

Performance Tips

ItCompiles.Data.Tracked is designed around the idea that most application code reads data far more often than it edits data.

For the best performance, follow these guidelines:

Use the original object for read-only UI

When displaying data (tables, lists, dashboards, reports, etc.), read directly from the wrapped object.

tracked.Value.Name
tracked.Value.Quantity
tracked.Value.Tags.Count

This avoids initializing the change tracker for properties that are never edited.

Use tracked properties only while editing

When entering an edit mode, access the tracked property.

tracked.Property(x => x.Name).Value
tracked.Property(x => x.Name).SetValue("New Name")

This initializes tracking only for the values being edited.

Example

For a data table, prefer:

@tracked.Value.Name

instead of:

@tracked.Property(x => x.Name).Value

The first simply reads the underlying DTO.

The second initializes and accesses the change tracker, which is unnecessary if the value is only being displayed.

Why?

The library uses lazy initialization to avoid creating tracking objects until they are actually needed.

Accessing a tracked property may create tracking metadata for that object, while reading from Value simply accesses the original DTO.

This design keeps rendering extremely fast in UI frameworks such as Blazor, where components may render many times in response to user interaction.

  • Display data using tracked.Value.
  • Enter edit mode only when the user begins editing.
  • Read and modify values through Property(), Object(), and Collection() while editing.
  • Call Commit() to apply changes to the original object, or Rollback() to discard them.

Following this pattern provides the best balance between performance and change tracking, especially for large object graphs and data-heavy user interfaces.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net8.0

    • 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.

Version Downloads Last Updated
0.1.0-preview 120 8/10/2026