elsa-core/src/modules/Elsa.Persistence.EFCore.Common/JsonValueComparer.cs
Sipke Schoorstra 2c0b3da5de
Addresses warnings and enforces null safety (#7051)
* Enhance null-safety annotations across modules and refactor for improved consistency:

- Added `null!` annotations to enforce non-nullability expectations.
- Updated workflows, tests, and runtime services to handle default null values reliably.
- Removed obsolete and unused APIs, simplifying interfaces and improving maintainability.
- Refactored methods and properties for clarity, thread-safety, and consistency.
- Adjusted test configurations for code coverage tracking and integration improvements.

* Refactor activity iteration in container serialization tests to simplify type casting.
2025-11-12 16:56:31 +01:00

49 lines
1.4 KiB
C#

using System.Text.Json;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace Elsa.Persistence.EFCore;
/// <summary>
/// Compares two objects.
/// Required to make EF Core change tracking work for complex value converted objects.
/// </summary>
/// <remarks>
/// For objects that implement <see cref="ICloneable"/> and <see cref="IEquatable{T}"/>,
/// those implementations will be used for cloning and equality.
/// For plain objects, fall back to deep equality comparison using JSON serialization
/// (safe, but inefficient).
/// </remarks>
public class JsonValueComparer<T>() : ValueComparer<T>((t1, t2) => DoEquals(t1!, t2!),
t => DoGetHashCode(t),
t => DoGetSnapshot(t))
{
private static string Json(T instance) {
return JsonSerializer.Serialize(instance);
}
private static T DoGetSnapshot(T instance) {
if (instance is ICloneable cloneable)
return (T)cloneable.Clone();
return JsonSerializer.Deserialize<T>(Json(instance))!;
}
private static int DoGetHashCode(T instance) {
if (instance is IEquatable<T>)
return instance.GetHashCode();
return Json(instance).GetHashCode();
}
private static bool DoEquals(T left, T right) {
if (left is IEquatable<T> equatable)
return equatable.Equals(right);
return Json(left).Equals(Json(right));
}
}