{"id":13825383,"url":"https://github.com/Dynalon/JsonConfig","last_synced_at":"2025-07-08T21:32:19.779Z","repository":{"id":4207903,"uuid":"5328133","full_name":"Dynalon/JsonConfig","owner":"Dynalon","description":"simple configuration library using JSON and C# 4.0 dynamic feature","archived":false,"fork":false,"pushed_at":"2015-09-22T00:11:06.000Z","size":816,"stargazers_count":205,"open_issues_count":11,"forks_count":65,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-06-09T04:15:34.257Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/Dynalon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-08-07T13:22:30.000Z","updated_at":"2025-04-16T02:22:12.000Z","dependencies_parsed_at":"2022-08-24T22:30:32.747Z","dependency_job_id":null,"html_url":"https://github.com/Dynalon/JsonConfig","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Dynalon/JsonConfig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynalon%2FJsonConfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynalon%2FJsonConfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynalon%2FJsonConfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynalon%2FJsonConfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dynalon","download_url":"https://codeload.github.com/Dynalon/JsonConfig/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynalon%2FJsonConfig/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264352824,"owners_count":23594981,"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":[],"created_at":"2024-08-04T09:01:19.931Z","updated_at":"2025-07-08T21:32:19.348Z","avatar_url":"https://github.com/Dynalon.png","language":"C#","funding_links":[],"categories":["C# #"],"sub_categories":[],"readme":"JsonConfig README\n=====================\n\n## About\nJsonConfig is a simple to use configuration library, allowing JSON based config\nfiles for your C#/.NET application instead of cumbersome\nweb.config/application.config xml files.\n\nIt is based on JsonFX and C# 4.0 dynamic feature. Allows putting your programs\nconfig file into .json files, where a default config can be embedded as a\nresource or put in the (web-)application folder. Configuration can be accessed\nvia dynamic types, no custom classes or any other stub code is necessary.\n\nJsonConfig brings support for *config inheritance*, meaning a set of\nconfiguration files can be used to have a single, scoped configuration at\nruntime which is a merged version of all provided configuration files.\n\n## Example\n\nSince my lack of skills in writing good examples into a documentation file, it\nis best to take a look at the examples/ folder with a complete commented .sln\nwhich will give you a better understanding (TODO).\n\n### Getting started\n\nUsually the developer wants a default configuration that is used when no\nconfiguration by the user is present whatsoever. Often, this configuration is\njust hardcoded default values within the code. With JsonConfig there is no need\nfor hardcoding, we simply create a default.conf file and embedd it as a\nresource.\n\nLet's create a sample default.conf for a hypothetical grocery store:\n\n\t# Lines beginning with # are skipped when the JSON is parsed, so we can\n\t# put comments into our JSON configuration files\n\t{\n\t\tStoreOwner : \"John Doe\",\n\t\t\n\t\t# List of items that we sell\n\t\tFruits: [ \"apple\", \"banana\", \"pear\" ]\n\t}\n\nJsonConfig automatically scan's all assemblies for the presence of a\ndefault.conf file, so we do not have to add any boilerplate code and can\ndirectly dive in:\n```csharp\n// exmaple code using our configuration file\nusing JsonConfig;\n[...]\npublic void PrintInfo () {\n\tvar storeOwner = Config.Default.StoreOwner;\n\n\tConsole.WriteLine (\"Hi there, my name is {0}!\", storeOwner);\n\n\tforeach (var fruit in Config.Default.Fruits)\n\t\tConsole.WriteLine (fruit);\n\n}\n```\n\nHowever, the developer wants the user to make his own configuration file.\nJsonConfig automatically scans for a settings.conf file in the root path of the\napplication.\n\n\t# sample settings.conf\n\t{\n\t\tFruits: [ \"melon\", \"peach\" ]\t\n\t}\n\nThe settings.conf and the default.conf are then merged in a clever\nway and provided via the *Global* configuration.\n```csharp\npublic void PrintInfo () {\n\t// will result in apple, banana, pear \n\tforeach (var fruit in Config.Default.Fruits)\n\t\tConsole.WriteLine (fruit);\n\n\t// will result in melon, peach\n\tforeach (var fruit in Config.User.Fruits)\n\t\tConsole.WriteLine (fruit);\n\n\t// access the Global scope, which is a merge of Default\n\t// and User configuration\n\t// will result in apple, banana, pear, melon, peach\n\tforeach (var fruit in Config.Global.Fruits)\n\t\tConsole.WriteLine (fruit);\n\n}\n```\n### Nesting objects\n\nWe are not bound to any hierarchies, any valid JSON is a valid configuration\nobject. Take for example a hypothetical webserver configuration:\n\n\t{\n\t\tListenPorts: [ 80, 443 ],\n\t\tEnableCaching : true,\n\t\tServerProgramName: \"Hypothetical WebServer 1.0\",\n\n\t\tWebsites: [\n\t\t\t{\n\t\t\t\tPath: \"/srv/www/example/\",\n\t\t\t\tDomain: \"example.com\",\n\t\t\t\tContact: \"admin@example.com\"\t\n\t\t\t},\n\t\t\t{\n\t\t\t\tPath: \"/srv/www/somedomain/\",\n\t\t\t\tDomain: \"somedomain.com\",\n\t\t\t\tContact: \"admin@somedomain.com\"\n\t\t\t}\n\t\t]\n\t}\t\n\nAbove configuration could be accessed via:\n\n```csharp\nusing JsonConfig;\n[...]\n\npublic void StartWebserver () {\n\t// access via Config.Global\n\tstring serverName = Config.Global.ServerProgramName;\n\tbool caching = Config.Global.EnableCaching;\n\tint[] listenPorts = Config.Global.ListenPorts;\n\n\tforeach (dynamic website in Config.Global.Websites) {\n\t\tStartNewVhost (website.Path, website.Domain, website.Contact);\n\t}\n}\n```\n\n### \"Magic\" prevention of null pointer exceptions\n\nChoosing reasonable default values is only a matter of supplying a good\ndefault.conf. But using some C# 4.0 dynamic \"magic\", non-existant configuration\nvalues will not throw a NullPointer exception:\n\n```csharp\n// we are lazy and do not want to give default values for configuration\n// objects, but just want them to be false\n\n// there is no need to have LoadedModules OR HttpServer in your\n// default.conf, if missing this will just evaluate to false\nif (Config.Global.LoadedModules.HttpServer) {\n\t// start HttpServer\n}\n\n// more drastic example, its safe to write\nif (Config.Global.nonexistant.field.that.never.will.be.given) {\n\t// this will never be run unless you create that structure in your\n\t// config files\n}\n\n// when the configuration value is cast to string, it will be null if not\n// given\nif (string.IsNullOrEmpty (Config.Global.some.nonexistant.nested.field)) {\n\t// will most likely be run all the times\n}\n```\n\nThe \"magic\" allows you to cast a not-yet existing field to common types, which will then have empty or default values:\n```csharp\nforeach (string name in Config.Global.NonExistantField as string[]) {\n\t// instead of being cast to null, if a non-existing field is cast to string[] it\n\t// will just be an empty array: string[] { }\n\tConsole.WriteLine (name);\n}\n\n// works for nullable types, too. Nullable types will\n// cast to null if not exsisting in the config.\nvar processFiles = (bool?) Config.Global.ProcessFiles;\nif (processFiles != null) {\n\t// will only be run if ProcessFiles is present in the config\n\tDoSomethingWithDirectory (processFiles);\n}\n```\n\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Dynalon/jsonconfig/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDynalon%2FJsonConfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDynalon%2FJsonConfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDynalon%2FJsonConfig/lists"}