SnapshotManager 1.1.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package SnapshotManager --version 1.1.3
                    
NuGet\Install-Package SnapshotManager -Version 1.1.3
                    
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="SnapshotManager" Version="1.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SnapshotManager" Version="1.1.3" />
                    
Directory.Packages.props
<PackageReference Include="SnapshotManager" />
                    
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 SnapshotManager --version 1.1.3
                    
#r "nuget: SnapshotManager, 1.1.3"
                    
#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 SnapshotManager@1.1.3
                    
#: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=SnapshotManager&version=1.1.3
                    
Install as a Cake Addin
#tool nuget:?package=SnapshotManager&version=1.1.3
                    
Install as a Cake Tool

SnapshotManager

一个轻量级、泛型的 C# 快照管理与差异对比库。 专为处理复杂数据结构(如列表、矩阵、自定义对象)的历史版本管理和差异分析而设计。


📖 快速上手指南

1. 第一步:定义你的数据类 (Element)

你的数据类必须继承 ElementBase 并实现 DeepClone 方法。这是为了确保快照存储的是数据的副本,而不是引用。

using SnapshotManager.core;

// 定义一个简单的业务对象
public class MyData : ElementBase
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double Score { get; set; }

    // 必须实现:深拷贝逻辑
    public override ElementBase DeepClone()
    {
        return new MyData 
        { 
            Id = this.Id, 
            Name = this.Name, 
            Score = this.Score 
        };
    }
}

2. 第二步:初始化管理器

我们提供了一个工厂方法,专门用于管理 List<List<ElementBase>> (二维矩阵) 类型的数据。

using SnapshotManager.core;

// 创建管理器实例
var manager = ElementSnapshotManagerFactory.Create();

3. 第三步:创建快照 (Take Snapshot)

你不需要手动创建复杂的 Snapshot 对象,直接把你的数据扔给管理器即可。

// 1. 准备初始数据
var data = new List<List<ElementBase>>
{
    new() { new MyData { Id = 1, Name = "Alice", Score = 80 } },
    new() { new MyData { Id = 2, Name = "Bob", Score = 90 } }
};

// 2. 存快照 (方式 A:自动生成时间戳 Key)
string v1Key = manager.TakeSnapshot(data); 
Console.WriteLine($"已保存快照: {v1Key}");

// 3. 存快照 (方式 B:指定自定义 Key)
manager.TakeSnapshot("Version_1.0", data);

4. 第四步:修改数据并对比 (Diff)

这是最强大的功能。你可以修改内存中的数据,然后直接和之前的快照进行对比,查看发生了什么变化。

// 1. 修改数据:修改 Alice 的分数,删除 Bob
((MyData)data[0][0]).Score = 95; 
data.RemoveAt(1); 

// 2. 【实时对比】当前数据 vs "Version_1.0" 快照
var diffNode = manager.DiffWith("Version_1.0", data);

// 3. 【历史对比】对比两个已存储的快照 (假设你存了 v1 和 v2)
// var historyDiff = manager.Diff("Version_1.0", "Version_2.0");

5. 第五步:打印差异结果

我们提供了打印机类,可以将复杂的 Diff 树状结构可视化输出。

using SnapshotManager.core;

// 1. 创建控制台打印机
var printer = new ConsoleDiffPrinter();

// 2. 打印结果
// 绿色 = 新增, 红色 = 删除, 黄色 = 修改
printer.Print(diffNode);

输出示例:

ListDiff (Modified)
  Row[0] (Modified)
    Col[0] (Modified)
      Score: 80 -> 95 (Modified)
  Row[1] (Removed)

🛠️ 进阶:如何实现自定义 Diff 算法?

如果你不想用默认的反射对比,或者你的数据结构不是二维数组,你可以自定义 Diff 算法。

1. 实现 IDiff 接口

public class MyCustomDiff : IDiff<MyComplexData>
{
    public DiffNode Diff(MyComplexData? oldVal, MyComplexData? newVal)
    {
        var node = new DiffNode { Name = "MyData" };
        
        // 在这里写你的对比逻辑...
        if (oldVal.Value != newVal.Value)
        {
            node.Type = DiffType.Modified;
            node.OldValue = oldVal.Value;
            node.NewValue = newVal.Value;
        }
        
        return node;
    }
}

2. 组装 Manager

var myManager = new SnapshotManager<MyComplexData>(
    new MyCustomDiff(),            // 1. 你的 Diff 算法
    (key, data) => new Snapshot<MyComplexData>(key, data) // 2. 告诉 Manager 如何包装快照
);

🏗️ 核心概念

  • SnapshotManager: 总管家。负责存取快照、执行 Diff。
  • Snapshot: 数据的容器。它会在内部深拷贝一份数据,防止外部修改影响历史记录。
  • DiffNode: 差异树节点。包含差异类型(Added/Removed/Modified)、旧值、新值以及子节点。
  • ElementBase: 所有数据项的基类,强制要求实现深拷贝。

📦 打包与发布

在 .NET 项目中,我们使用 dotnet pack 命令来生成 NuGet 包。请在终端(Terminal)中运行以下命令:

dotnet pack -c Release
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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 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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 is compatible.  net481 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.2.2 112 3/24/2026
1.2.1 98 3/23/2026
1.2.0 99 3/23/2026
1.1.3 109 3/23/2026
1.1.1 96 3/22/2026
1.1.0 96 3/22/2026
1.0.0 676 12/3/2025

- Feat: 新增 TakeSnapshot API,支持直接保存数据对象,无需手动创建 Snapshot 实例。
- Feat: 新增 DiffWith API,支持将当前内存数据与历史快照直接对比,无需先保存快照。
- Docs: 完善了核心接口的 XML 文档注释,提供更好的 IntelliSense 支持。
- Docs: 重写 README,提供更清晰的实战引导。