{"id":17255571,"url":"https://github.com/ffmathy/fluffyspoon.changedetection","last_synced_at":"2025-07-29T22:31:36.867Z","repository":{"id":48569725,"uuid":"232370140","full_name":"ffMathy/FluffySpoon.ChangeDetection","owner":"ffMathy","description":"Allows you to compare what changes have been made between two values or objects.","archived":false,"fork":false,"pushed_at":"2021-07-20T04:43:45.000Z","size":44,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-22T22:03:26.017Z","etag":null,"topics":["change","change-detection","csharp"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ffMathy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-07T16:44:26.000Z","updated_at":"2021-07-20T04:43:47.000Z","dependencies_parsed_at":"2022-09-23T19:32:07.544Z","dependency_job_id":null,"html_url":"https://github.com/ffMathy/FluffySpoon.ChangeDetection","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffMathy%2FFluffySpoon.ChangeDetection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffMathy%2FFluffySpoon.ChangeDetection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffMathy%2FFluffySpoon.ChangeDetection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ffMathy%2FFluffySpoon.ChangeDetection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ffMathy","download_url":"https://codeload.github.com/ffMathy/FluffySpoon.ChangeDetection/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228054246,"owners_count":17862126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["change","change-detection","csharp"],"created_at":"2024-10-15T07:12:03.794Z","updated_at":"2024-12-04T05:40:44.428Z","avatar_url":"https://github.com/ffMathy.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"Allows you to compare what changes have been made between two values or objects.\n\n# Install the package from NuGet\n`install-package FluffySpoon.ChangeDetection`\n\n# Usage\nIn the examples below, the changes are of type `Change` which looks like this:\n\n```csharp\npublic struct Change\n{\n    /// \u003csummary\u003e\n    /// The path of the property that changed.\n    /// \u003cexample\u003e\u003csee cref=\"string.Empty\"/\u003e for simple values.\u003c/example\u003e\n    /// \u003cexample\u003e\"MyComplexObject.MyComplexSubObject.MySimpleValue\" when comparing two MyComplexObject instances.\u003c/example\u003e\n    /// \u003c/summary\u003e\n    public string PropertyPath\n    {\n        get;\n    }\n\n    /// \u003csummary\u003e\n    /// The old value.\n    /// \u003c/summary\u003e\n    public object OldValue\n    {\n        get; \n    }\n\n    /// \u003csummary\u003e\n    /// The new value.\n    /// \u003c/summary\u003e\n    public object NewValue\n    {\n        get;\n    }\n}\n```\n\n## Comparing simple values\n```csharp\nChangeDetector.GetChange(\"foo\", \"bar\");\n\n/* returns:\n{\n    PropertyPath: \"\",\n    OldValue: \"foo\",\n    NewValue: \"bar\"\n}\n*/\n```\n\n## Comparing complex objects recursively\nConsider the following complex class for the examples below:\n\n```csharp\nclass ComplexObject\n{\n    public string StringValue\n    {\n        get; set;\n    }\n\n    public int MyIntValue\n    {\n        get; set;\n    }\n\n    public ComplexObject SubObject\n    {\n        get; set;\n    }\n}\n```\n\n### Example: Comparing object with sub-object\n```csharp\nvar a = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 28,\n    SubObject = new ComplexObject() {\n        StringValue = \"bar\",\n        MyIntValue = 123\n    }\n};\n\nvar b = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 1337,\n    SubObject = new ComplexObject() {\n        StringValue = \"baz\",\n        MyIntValue = 123\n    }\n};\n\nChangeDetector.GetChanges(a, b);\n\n/* returns:\n[\n    {\n        PropertyPath: \"MyIntValue\",\n        OldValue: 28,\n        NewValue: 1337\n    },\n    {\n        PropertyPath: \"SubObject.StringValue\",\n        OldValue: \"bar\",\n        NewValue: \"baz\"\n    }\n]\n*/\n```\n\n### Example: Comparing specific complex object property (SubObject)\n```csharp\nvar a = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 28,\n    SubObject = new ComplexObject() {\n        StringValue = \"bar\",\n        MyIntValue = 123\n    }\n};\n\nvar b = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 1337,\n    SubObject = new ComplexObject() {\n        StringValue = \"baz\",\n        MyIntValue = 123\n    }\n};\n\nChangeDetector.GetChanges(a, b, x =\u003e x.SubObject);\n\n/* returns:\n[\n    {\n        PropertyPath: \"StringValue\",\n        OldValue: \"bar\",\n        NewValue: \"baz\"\n    }\n]\n*/\n```\n\n### Example: Comparing specific simple value on object (MyIntValue)\n```csharp\nvar a = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 28,\n    SubObject = new ComplexObject() {\n        StringValue = \"bar\",\n        MyIntValue = 123\n    }\n};\n\nvar b = new ComplexObject() {\n    StringValue = \"foo\",\n    MyIntValue = 1337,\n    SubObject = new ComplexObject() {\n        StringValue = \"baz\",\n        MyIntValue = 123\n    }\n};\n\nChangeDetector.GetChanges(a, b, x =\u003e x.MyIntValue);\n\n/* returns:\n[\n    {\n        PropertyPath: \"MyIntValue\",\n        OldValue: 28,\n        NewValue: 1337\n    }\n]\n*/\n```\n\n## Checking if a change is present\nInstead of `GetChange` and `GetChanges`, you can use `HasChanges` to get a boolean indicating if any change has been detected or not.\n\n### Checking among existing changes\nIn addition to the `HasChanges` and `HasChange` methods, you can also check if a specific property has changed among existing changes.\n\n```csharp\nvar changes = ChangeDetector.GetChanges(a, b, x =\u003e x.MyIntValue);\n\nchanges.HasChangeFor(x =\u003e x.MyIntValue); //returns a bool\nchanges.HasChangeFor(\"MyIntValue\"); //returns a bool\n```\n\n## Circular references won't break the comparison\nIf circular references are detected, the given property that causes the circular dependency is not evaluated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffmathy%2Ffluffyspoon.changedetection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fffmathy%2Ffluffyspoon.changedetection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fffmathy%2Ffluffyspoon.changedetection/lists"}