TextDiffLibrary 1.0.2
dotnet add package TextDiffLibrary --version 1.0.2
NuGet\Install-Package TextDiffLibrary -Version 1.0.2
<PackageReference Include="TextDiffLibrary" Version="1.0.2" />
<PackageVersion Include="TextDiffLibrary" Version="1.0.2" />
<PackageReference Include="TextDiffLibrary" />
paket add TextDiffLibrary --version 1.0.2
#r "nuget: TextDiffLibrary, 1.0.2"
#:package TextDiffLibrary@1.0.2
#addin nuget:?package=TextDiffLibrary&version=1.0.2
#tool nuget:?package=TextDiffLibrary&version=1.0.2
TextDiffLibrary
TextDiffLibrary is a high-performance text comparison library for .NET 9.0, implementing the Myers diff algorithm with support for both line-level and character-level differences. Ideal for comparing SQL stored procedures, configuration files, or any text content.
โจ Features
- ๐ Myers Diff Algorithm - Industry-standard, efficient O(ND) complexity
- ๐ Line & Character Level Diffs - Detailed change tracking
- ๐จ Multiple Output Formats:
- Excel DTO - Side-by-side comparison for spreadsheet export
- JSON - Structured data for API integration
- Unified Diff - Git-compatible patch format
- HTML - Rich visual comparison with syntax highlighting
- โ๏ธ Configurable Options:
- Ignore whitespace/case/empty lines
- Character-level diff toggle
- Custom context lines for unified diff
- ๐ Dependency Injection Ready - Built-in DI support with
AddTextDiffLibrary() - ๐ง Async Support - Non-blocking diff computation
- ๐ Strongly Typed - Full C# nullable reference types support
๐ฆ Installation
NuGet Package Manager
Install-Package TextDiffLibrary
.NET CLI
dotnet add package TextDiffLibrary
Package Reference
<PackageReference Include="TextDiffLibrary" Version="1.0.0" />
๐ Quick Start
1. Setup Dependency Injection
using Microsoft.Extensions.DependencyInjection;
using TextDiffLibrary.Core.Extensions;
var services = new ServiceCollection();
services.AddTextDiffLibrary();
var serviceProvider = services.BuildServiceProvider();
2. Basic Text Comparison
using TextDiffLibrary.Contracts.Interfaces;
using TextDiffLibrary.Contracts.Models;
// Get the differ service
var differ = serviceProvider.GetRequiredService<ITextDiffer>();
// Source and target texts
string sourceText = """
SELECT * FROM Users
WHERE Age > 18
ORDER BY Name
""";
string targetText = """
SELECT Name, Email FROM Users
WHERE Age > 21
ORDER BY Email
""";
// Configure comparison options
var options = DiffOptions.CreateDefault(); // or customize
// Create comparison context
var context = ComparisonContext.Create(sourceText, targetText, options);
// Perform comparison
var result = differ.Compare(context);
// Access results
Console.WriteLine($"Total Changes: {result.Statistics.TotalChanges}");
Console.WriteLine($"Added: {result.Statistics.AddedLines}");
Console.WriteLine($"Deleted: {result.Statistics.DeletedLines}");
Console.WriteLine($"Modified: {result.Statistics.ModifiedLines}");
3. Iterate Over Changes
foreach (var line in result.Lines)
{
Console.WriteLine($"[{line.ChangeType}] Line {line.SourceLineNumber ?? line.TargetLineNumber}");
if (line.ChangeType == ChangeType.Modified && line.CharacterChanges != null)
{
foreach (var charChange in line.CharacterChanges)
{
Console.WriteLine($" Char change at pos {charChange.Position}: {charChange.OldValue} โ {charChange.NewValue}");
}
}
}
๐จ Output Formats
JSON Output
using TextDiffLibrary.Contracts.Interfaces;
var formatterFactory = serviceProvider.GetRequiredService<IFormatterFactory>();
// Use type-safe enum
var jsonFormatter = formatterFactory.GetFormatter<string>(FormatterType.Json);
var json = jsonFormatter.Format(result);
File.WriteAllText("diff-result.json", json);
Unified Diff (Git-compatible)
var unifiedFormatter = formatterFactory.GetFormatter<string>(FormatterType.Unified);
var patch = unifiedFormatter.Format(result);
File.WriteAllText("changes.patch", patch);
// Apply with: git apply changes.patch
HTML Report
var htmlFormatter = formatterFactory.GetFormatter<string>(FormatterType.Html);
var html = htmlFormatter.Format(result);
File.WriteAllText("diff-report.html", html);
Process.Start(new ProcessStartInfo("diff-report.html") { UseShellExecute = true });
Excel DTO (for spreadsheet export)
using TextDiffLibrary.Contracts.DTOs;
var excelFormatter = formatterFactory.GetFormatter<ExcelDiffDto>(FormatterType.Excel);
var excelDto = excelFormatter.Format(result);
foreach (var row in excelDto.Rows)
{
Console.WriteLine($"{row.Status}: {row.SourceContent} โ {row.TargetContent}");
}
โ๏ธ Configuration Options
DiffOptions
var options = new DiffOptions
{
IgnoreWhitespace = true, // Normalize whitespace differences
IgnoreCase = true, // Case-insensitive comparison
IgnoreEmptyLines = true, // Skip empty lines
EnableCharacterLevelDiff = true // Compute character-level changes for Modified lines
};
Configure via appsettings.json
{
"TextDiffLibrary": {
"DefaultIgnoreWhitespace": true,
"DefaultIgnoreCase": true,
"DefaultIgnoreEmptyLines": true,
"DefaultEnableCharacterDiff": true,
"UnifiedDiffContextLines": 3,
"EnablePerformanceLogging": false
}
}
// Program.cs (ASP.NET Core / Web API)
builder.Services.AddTextDiffLibrary(options =>
{
builder.Configuration.GetSection("TextDiffLibrary").Bind(options);
options.Validate();
});
๐๏ธ Architecture
TextDiffLibrary
โโโ TextDiffLibrary.Contracts - Interfaces, Models, DTOs
โโโ TextDiffLibrary.Core - Myers Algorithm, Services
โโโ TextDiffLibrary.Formatters - Output Formatters (JSON, HTML, etc.)
Key Interfaces
ITextDiffer- Main diff computation serviceITextNormalizer- Text preprocessing (whitespace, case)IMyersDiffEngine- Core Myers diff algorithmICharacterDiffer- Character-level diff for modified linesIOutputFormatter<TOutput>- Generic formatter interfaceIFormatterFactory- Formatter resolution (by string or enum)
๐ Advanced Usage
Async Comparison
var result = await differ.CompareAsync(context, cancellationToken);
Custom JSON Serialization Options
builder.Services.AddTextDiffLibrary(options =>
{
options.JsonSerializerOptions = new JsonSerializerOptions
{
WriteIndented = false,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
});
E2E Workflow with DiffService
using TextDiffLibrary.Core.Services;
var diffService = serviceProvider.GetRequiredService<DiffService>();
// Compute diff and format in one call (uses configured options if null)
var json = diffService.ComputeAndFormat<string>(sourceText, targetText, null, FormatterType.Json);
var html = diffService.ComputeAndFormat<string>(sourceText, targetText, null, FormatterType.Html);
๐ง Customization
Create Custom Formatter
public class MarkdownFormatter : IOutputFormatter<string>
{
public string Format(DiffResult result)
{
var sb = new StringBuilder();
sb.AppendLine("# Diff Report");
foreach (var line in result.Lines)
{
sb.AppendLine($"- **{line.ChangeType}**: {line.SourceContent ?? line.TargetContent}");
}
return sb.ToString();
}
}
// Register in DI
services.AddSingleton<MarkdownFormatter>();
๐ Performance
- Algorithm: Myers diff - O(ND) time complexity (N = input size, D = edit distance)
- Memory: O(N) with trace optimization
- Optimizations:
- String hashing for fast equality checks
- Early termination for identical files
- Efficient line pairing with similarity threshold (80%)
Benchmarks (example)
| Input Size | Time (ms) | Memory (MB) |
|---|---|---|
| 100 lines | 5 ms | 2 MB |
| 1,000 lines | 50 ms | 15 MB |
| 5,000 lines | 250 ms | 70 MB |
๐งช Testing
The library includes comprehensive test coverage:
- 118+ unit tests covering all components
- Integration tests for E2E workflows
- Edge case handling (empty files, identical files, all changes)
dotnet test
# Test summary: total: 118; failed: 0; succeeded: 118; skipped: 0
๐ License
This project is licensed under the MIT License. See LICENSE for details.
๐ค Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
๐ Changelog
v1.0.0 (2026-01-27)
- โจ Initial release
- ๐ Myers diff algorithm implementation
- ๐ Line and character-level diff support
- ๐จ Four output formatters (Excel DTO, JSON, Unified Diff, HTML)
- โ๏ธ Configurable comparison options
- ๐ Dependency injection integration
- ๐ง Async support
๐ Links
๐ก Use Cases
- ๐ SQL Stored Procedure Comparison - Track changes in database schema
- ๐ง Configuration File Diffs - Monitor application config changes
- ๐ Document Versioning - Compare text document revisions
- ๐ API Response Validation - Diff JSON/XML responses
- ๐งช Test Result Comparison - Validate test output changes
๐ฅ Authors
Maintained by the TextDiffLibrary contributors.
Happy Diffing! ๐
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 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. |
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.2)
- Microsoft.Extensions.Options (>= 9.0.0)
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.0.2 | 31 | 2/24/2026 |
v1.0.2 - Added word-level diff support with DetailLevel enum (None/Character/Word). Tokenizes words, whitespace, and punctuation separately. Replaced EnableCharacterLevelDiff with DetailLevel property for better extensibility. HTML formatter now highlights character and word changes with darker colors. Fully backward compatible via DI.