{"id":21954810,"url":"https://github.com/mgernand/objectdelta","last_synced_at":"2025-04-23T12:11:56.988Z","repository":{"id":38300164,"uuid":"480750520","full_name":"mgernand/ObjectDelta","owner":"mgernand","description":"Computes the delta of two object instances.","archived":false,"fork":false,"pushed_at":"2025-03-03T11:47:05.000Z","size":78,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T12:04:32.311Z","etag":null,"topics":["delta","difference","dotnet","dotnet-core","object"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgernand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-04-12T09:58:46.000Z","updated_at":"2025-03-10T15:54:12.000Z","dependencies_parsed_at":"2023-11-16T12:27:15.602Z","dependency_job_id":"952220b2-8b20-438a-8fde-d8041972308e","html_url":"https://github.com/mgernand/ObjectDelta","commit_stats":{"total_commits":18,"total_committers":2,"mean_commits":9.0,"dds":"0.38888888888888884","last_synced_commit":"025bebb9c4075861f34cc10c8df2269b3abfbc63"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FObjectDelta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FObjectDelta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FObjectDelta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgernand%2FObjectDelta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgernand","download_url":"https://codeload.github.com/mgernand/ObjectDelta/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250430593,"owners_count":21429324,"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":["delta","difference","dotnet","dotnet-core","object"],"created_at":"2024-11-29T07:26:11.438Z","updated_at":"2025-04-23T12:11:56.959Z","avatar_url":"https://github.com/mgernand.png","language":"C#","readme":"# ObjectDelta\n\nA libary that creates a delta of two object instances.\n\nThe library is inspired by a blog post of [Daniel Wertheim](https://github.com/danielwertheim) about\nproducing a delta of two objects of the same type using the library [Structurizer](https://github.com/danielwertheim/structurizer).\nUnfortunately [Structurizer](https://github.com/danielwertheim/structurizer) will not provide index information \nfor properties with a ```null``` value, the property of a collection and for ```null``` collection items.\nThis information is needed to be able to record object changes from ```null``` to a value and vice versa. \nI decided to create a library based on [Structurizer](https://github.com/danielwertheim/structurizer) that fits \nmy needs for the delta creation.\n\n## Usage\n\n```C#\nCustomer first = new Customer\n{\n\tFirstName = \"Sherlock\",\n\tLastName = \"Olmes\",\n\tAddress = new Address\n\t{\n\t\tStreet = \"Baker Street\",\n\t\tNumber = \"900\",\n\t\tZip = \"NW1\",\n\t\tCity = \"London\",\n\t\tCountry = \"England\"\n\t},\n\tTags = new string[] { \"detective\", \"addict\" }\n};\n\nCustomer second = new Customer\n{\n\tFirstName = \"Sherlock\",\n\tLastName = \"Holmes\",\n\tAddress = new Address\n\t{\n\t\tStreet = \"Baker Street\",\n\t\tNumber = \"221b\",\n\t\tZip = \"NW1\",\n\t\tCity = \"London\",\n\t\tCountry = \"England\"\n\t},\n\tTags = new string[] { \"detective\", \"genius\", \"addict\" }\n};\n\nObjectDelta\u003cCustomer\u003e result = ObjectComparer.Compare(first, second);\n```\n\nThe resulting ```ObjectDelta\u003cCustomer\u003e``` provides a flat list containing the deltas for every property,\ninclusing nested properties of complex types (like the ```Address```) and colleection items. \n\nThe output of ```ToString()``` of the result of operation above:\n\n```plain\nLastName (Olmes =\u003e Holmes)\nAddress (ConsoleApp1.Address =\u003e ConsoleApp1.Address)\nAddress.Number (900 =\u003e 221b)\nTags (System.String[] =\u003e System.String[])\nTags[1] (addict =\u003e genius)\nTags[2] (null =\u003e addict)\n```\n\n## Structure\n\nThis creates a flat structure for types and a flat key-value structure for instances.\n\n### Usage\n\nIf you just ant to create the schema of a type just pass it to the ```IStructureBuilder```.\n\n```C#\nIStructureBuilder builder = new StructureBuilder();\nStructure structure = builder.CreateStructure\u003cCustomer\u003e();\n\nConsole.WriteLine(structure.Schema);\n```\n\nThis will result in a flat list of the property structure of the type ```Customer```.\n\n```plain\nFirstName\nLastName\nAddress\nAddress.Street\nAddress.Number\nAddress.Zip\nAddress.City\nAddress.Country\nTags\n```\n\nTo create the schema and accessors for the values of an instance pass the instance to the ```IStructureBuilder```.\n\n```C#\nCustomer customer = new Customer\n{\n\tFirstName = \"Sherlock\",\n\tLastName = \"Holmes\",\n\tAddress = new Address\n\t{\n\t\tStreet = \"Baker Street\",\n\t\tNumber = \"221b\",\n\t\tZip = \"NW1\",\n\t\tCity = \"London\",\n\t\tCountry = \"England\"\n\t},\n\tTags = new string[] { \"detective\", \"addict\" }\n};\n\nIStructureBuilder builder = new StructureBuilder();\nStructure structure = builder.CreateStructure(customer);\n\nConsole.WriteLine(structure.Indices);\n```\n\nThis will result in a flat list of the property values in the given instance of type ```Customer```.\n\n```plain\nFirstName = \"Sherlock\"\nLastName = \"Holmes\"\nAddress = \"ConsoleApp1.Address\"\nAddress.Street = \"Baker Street\"\nAddress.Number = \"221b\"\nAddress.Zip = \"NW1\"\nAddress.City = \"London\"\nAddress.Country = \"England\"\nTags = \"System.String[]\"\nTags[0] = \"detective\"\nTags[1] = \"addict\"\n```\n\n## Acknowledgement\n\nMost of the terminology and code structure of the library comes from the libary [Structurizer](https://github.com/danielwertheim/structurizer)\nby [Daniel Wertheim](https://github.com/danielwertheim). This is basically a fork of his work which I bent to my needs, f.e. the need\nto support ```null``` values in index values and some other fixes and tweaks. I completely remove the configuration part and added the\nability to just get the schema of a type. The library this work is based on is licensed under the MIT license and so it this library.\n\n## References\n\n[Daniel Wertheim](https://github.com/danielwertheim)\n\t\n- [Structurizer](https://github.com/danielwertheim/structurizer)\n- [How to build a simple object graph delta comparer in C# using Structurizer](https://danielwertheim.se/how-to-build-a-simple-object-graph-delta-comparer-in-csharp-using-structurizer/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgernand%2Fobjectdelta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgernand%2Fobjectdelta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgernand%2Fobjectdelta/lists"}