{"id":18087989,"url":"https://github.com/slaks/confoxide","last_synced_at":"2025-08-01T20:11:16.888Z","repository":{"id":12891517,"uuid":"15568267","full_name":"SLaks/ConfOxide","owner":"SLaks","description":"Fast, DRY, strongly-typed configuration system for C# projects","archived":false,"fork":false,"pushed_at":"2017-07-17T15:33:01.000Z","size":4203,"stargazers_count":11,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-01T09:17:10.500Z","etag":null,"topics":["c-sharp","json","options-dialog","settings"],"latest_commit_sha":null,"homepage":null,"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/SLaks.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":"2014-01-01T18:39:53.000Z","updated_at":"2018-08-16T19:21:58.000Z","dependencies_parsed_at":"2022-09-06T10:50:30.188Z","dependency_job_id":null,"html_url":"https://github.com/SLaks/ConfOxide","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/SLaks/ConfOxide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SLaks%2FConfOxide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SLaks%2FConfOxide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SLaks%2FConfOxide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SLaks%2FConfOxide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SLaks","download_url":"https://codeload.github.com/SLaks/ConfOxide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SLaks%2FConfOxide/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268290739,"owners_count":24226646,"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","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["c-sharp","json","options-dialog","settings"],"created_at":"2024-10-31T17:10:14.828Z","updated_at":"2025-08-01T20:11:16.863Z","avatar_url":"https://github.com/SLaks.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ConfOxide\nConfOxide is a library for writing settings classes.  You can define your classes using simple C# auto-implemented properties, and ConfOxide will let you easily clone them, compare them, reset them, or save them to (and load them from) JSON files.\n\nInstall ConfOxide from [NuGet](https://www.nuget.org/packages/ConfOxide/).\n\n# Example\nFirst, create a settings class:\n\n```CSharp\nsealed class ConnectionSettings : SettingsBase\u003cConnectionSettings\u003e {\n\t[DefaultValue(2)]\n\tpublic int RetryCount { get; set; }\n\t[DefaultValue(\"00:00:30\")]\n\tpublic TimeSpan RetryDelay { get; set; }\n}\n\nsealed class MyAppSettings : SettingsBase\u003cMyAppSettings\u003e {\n\tpublic IList\u003cConnectionSettings\u003e Endpoints { get; private set; }\n\n\t[DefaultValue(\"2013-12-11\")]\n\tpublic DateTime TimelineStart { get; set; }\n\tpublic int? MaxAge { get; set; }\n}\n```\n\nNote that concrete settings classes must be `sealed`.  To create an inheritable settings class, you must add a type parameter; see below.\n\n## Usage\nTo create a new settings type, just write `new MyAppSettings()`.  All collection \u0026 settings properties will be initialized to new instances, and all properties will be set to their default values.  All settings methods are implemented as extension methods in the `ConfOxide.SettingsExtensions` class (for performance reasons); to call these methods, you will need to add `using ConfOxide`.\n\n## Working with JSON documents\n - To read a settings file from JSON, call `settings.ReadJson(json)` and pass a Json.NET `JObject` instance with the data to read.\n - To update a JSON object from an existing settings instance, call `settings.UpdateJson(json)` and pass the `JObject` to update.  The existing property order, as well as any extra properties, will be preserved.\n - To create a new JSON object from an existing settings instance, call `settings.ToJson()`.\n\n## Working with JSON files\nConfOxide also includes helper methods to read and write JSON files from disk.  Call `settings.ReadJsonFile(filename)` to read an existing JSON file, if it exists.  Call `settings.WriteJsonFile(filename)` to create or update a JSON file from the settings object\n\n## Working with Settings instances\n - Call `settings.IsEquivalentTo(otherSettings)` to check whether two settings instances hold the same values.  This is a deep comparison that will recursively compare collections and nested settings objects by value.\n - Call `settings.AssignFrom(sourceSettings)` to deeply assign the values from one settings instance to another.\n - Call `settings.CreateCopy()` to create a deep clone of a settings instance.  (this is shorthand for `new YourSettingsClass().AssignFrom(settings)`\n\nThese methods are particularly useful when creating cancellable Options dialogs.  You can call `settings.CreateCopy()` to bind your options dialog to a deep copy of the settings class, call `copy.IsEquivalentTo(copy)` to check whether there are any changes to apply, and call `settings.AssignFrom(copy)` to apply changes when clicking OK.\n\n## Supported types\nConfOxide supports properties of all basic .Net types, including primitive numeric types, `decimal`, `string`, `DateTime`, `DateTimeOffset`, and `TimeSpan`, all enums, as well as nullable types thereof.\nProperties containing other `SettingsBase\u003cT\u003e` classes are also supported, as long as there are no circular dependencies.\nConfOxide also supports collection properties of other `SettingsBase\u003cT\u003e` classes or of supported scalar types.  You can use any collection class that is writable, variable-sized, and has a default constructor.  If you make a property of type `IList\u003cT\u003e`, ConfOxide will create a `List\u003cT\u003e` to assign to the property.  Note that arrays are not supported.\n\n# FAQ\n - **Q: What does the name mean?**\u003cbr /\u003e\n     A: ConfOxide is a portmanteau of \u0026ldquo;Configuration\u0026rdquo; and \u0026ldquo;Carbon Dioxide\u0026rdquo; (dry ice).  The point of this library is to allow [DRY](http://en.wikipedia.org/wiki/Don't_repeat_yourself \"Don't Repeat Yourself\") configuration classes.\n\n - **Q: Wouldn't writing the serialization \u0026 cloning code by hand be faster?**\u003cbr /\u003e\n     A: Nope!  \n   ConfOxide uses advanced techniques to compile strongly-typed accessor code at runtime, avoiding all boxing (except when saving to JSON; Json.NET does not expose any way to save value types without boxing).  \nAt the cost of a slight longer initialization time (to build the accessor code for each type using reflection), ConfOxide should be exactly as fast as code you write by hand.\n\n - **Q: Why are all of the utility methods defined as extension methods?**\u003cbr /\u003e\n     A: To avoid extra casting.  Had those methods been defined in the base `SettingsBase\u003cT\u003e` class, it would have been impossible to access properties from derived classes without casting `this` (this is a limitation in C#'s type system).  By using extension methods with the [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern \"Curiously recurring template pattern\"), I can access the properties of `T` directly using pre-created delegates.\n\n - **Q: Do I need to write a constructor?**\u003cbr /\u003e\n     A: Nope!  The base `SettingsBase\u003cT\u003e` constructor will automatically initialize all nested collection \u0026 settings properties, and apply all declared default values.\n\n - **Q: How can I declare a default value for a collection property?**\u003cbr /\u003e\n     A: .Net doesn't provide any decent way to do that.  Instead, override the `ResetCustom()` and populate the collection in code.  This method will be called after each instance is constructed, as well as after `ResetValues()` is called.\n\n - **Q: Can I create a base classes with common properties and have multiple concrete settings classes inherit it?**\u003cbr /\u003e\n     A: Sure.  However, in order to make the type-safe accessor logic work, the intermediary class also needs to implement the [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern \"Curiously recurring template pattern\"):\n```CSharp\nabstract class VersionedSettingsBase\u003cT\u003e : SettingsBase\u003cT\u003e where T : VersionedSettingsBase\u003cT\u003e {\n\t[DefaultValue(1)]\n\tpublic int Version { get; set; }\n}\nsealed class MyAppSettings : VersionedSettingsBase\u003cMyAppSettings\u003e {\n\t// ...\n}\n``` \n\n - **Q: What about XML?**\u003cbr /\u003e\n     A: If enough people are interested in serializing to XML in addition to JSON, I'll add support for that.\n\n# License\n[MIT](http://opensource.org/licenses/MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslaks%2Fconfoxide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslaks%2Fconfoxide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslaks%2Fconfoxide/lists"}