{"id":28916905,"url":"https://github.com/ieuanwalker/appsettings","last_synced_at":"2026-03-16T18:34:02.149Z","repository":{"id":300240454,"uuid":"1005145211","full_name":"IeuanWalker/AppSettings","owner":"IeuanWalker","description":"Automatically generates the registration code for IOptions and can optionally validate them on startup using fluent validation.","archived":false,"fork":false,"pushed_at":"2025-06-20T15:45:31.000Z","size":419,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-20T16:10:56.003Z","etag":null,"topics":["config","configuration","csharp","dotnet","settings","source-generator"],"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/IeuanWalker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"IeuanWalker"}},"created_at":"2025-06-19T18:38:38.000Z","updated_at":"2025-06-20T16:03:46.000Z","dependencies_parsed_at":"2025-06-20T16:10:59.099Z","dependency_job_id":"f406fcab-d27f-46af-95cd-21ad1bfe93e5","html_url":"https://github.com/IeuanWalker/AppSettings","commit_stats":null,"previous_names":["ieuanwalker/appsettings"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/IeuanWalker/AppSettings","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IeuanWalker%2FAppSettings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IeuanWalker%2FAppSettings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IeuanWalker%2FAppSettings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IeuanWalker%2FAppSettings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IeuanWalker","download_url":"https://codeload.github.com/IeuanWalker/AppSettings/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IeuanWalker%2FAppSettings/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261212506,"owners_count":23125585,"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":["config","configuration","csharp","dotnet","settings","source-generator"],"created_at":"2025-06-22T00:09:17.938Z","updated_at":"2025-10-14T17:26:21.381Z","avatar_url":"https://github.com/IeuanWalker.png","language":"C#","funding_links":["https://github.com/sponsors/IeuanWalker"],"categories":[],"sub_categories":[],"readme":"# AppSettings [![Nuget](https://img.shields.io/nuget/v/IeuanWalker.AppSettings)](https://www.nuget.org/packages/IeuanWalker.AppSettings) [![Nuget](https://img.shields.io/nuget/dt/IeuanWalker.AppSettings)](https://www.nuget.org/packages/IeuanWalker.AppSettings) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n\nAutomatically generates the registration code for IOptions and can validate them on startup using [DataAnnotations](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-9.0#options-validation) or [fluent validation](https://docs.fluentvalidation.net/en/latest/).\n\n## How to use it?\n1. Install the [NuGet package](https://www.nuget.org/packages/IeuanWalker.AppSettings) into your project.\n```\nInstall-Package IeuanWalker.AppSettings\n```\n\n2. Inherit the `IAppSettings` interface onto the class that models your IOptions\n```csharp\npublic class ConfirmationEmailSettings : IAppSettings\n{\n\tpublic required string Subject { get; set; }\n}\n```\n3. Register the app settings\n   \u003e Once `IAppSettings` has been added to a class in your project, several extension methods will automatically be created.\n   \u003e The extension method name convention is AddAppSettingsFrom + your assembly name, and the namespace is your assembly name.\n\n    3.1 An extension method for `IServiceCollection` is created for all project types by default\n    ```csharp\n    builder.Services.AddAppSettingsFromApiProjectNestedClassLibrary(builder.Configuration);\n    ```\n    \n    3.2 If your project is a backend/blazor project, then it will also have an extension method for `IHostApplicationBuilder`, allowing you to easily chain the registration in your progam.cs\n    ```csharp\n    builder.AddAppSettingsFromApiProject();\n    ```\n    \n    3.3 If it's a MAUI project, it will also have an extension method for `MauiAppBuilder`, allowing you to easily chain the registration in your MauiProgam.cs\n    ```csharp\n    builder.AddAppSettingsFromMauiProject();\n    ```\n\n## Section name\nBy default, it maps the IOptions model to the section name based on the name of the model.\nFor example, the following model -\n```csharp\npublic class ConfirmationEmailSettings : IAppSettings\n{\n\tpublic required string Subject { get; set; }\n}\n```\n\nWould automatically map to the following app setting section -\n```json\n{\n  \"ConfirmationEmailSettings\": {\n    \"Subject\": \"Test subject\"\n  }\n}\n```\n\nIf your model name and configuration section don't match or you want to bind a nested configuration, you can override this within your model by using the `SectionName` attribute\n```csharp\n[SectionName(\"ConfirmationEmail\")]\npublic class ConfirmationEmailSettings : IAppSettings\n{\n    public required string Subject { get; set; }\n}\n```\n```csharp\n[SectionName(\"NestedConfiguration:ConfirmationEmail\")]\npublic class ConfirmationEmailSettings : IAppSettings\n{\n    public required string Subject { get; set; }\n}\n```\n\n## Validation\nYou can perform validation on startup using DataAnnotations or FluentValidation.\n\n### DataAnnotation\nAll you need to do is add a DataAnnotation attribute onto any property\n```csharp\npublic class ConfirmationEmailSettings : IAppSettings\n{\n\t[MinLength(5)]\n\tpublic required string Subject { get; set; }\n}\n```\n\n### FluentValidation\nTo use FluentValidation you need to create an `AbstractValidator` for your app settings model and add that validator to the `IAppSettings` inheritance.\n```csharp\npublic class ConfirmationEmailSettings : IAppSettings\u003cConfirmationEmailSettingsValidator\u003e\n{\n\tpublic required string Subject { get; set; }\n}\n\nsealed class ConfirmationEmailSettingsValidator : AbstractValidator\u003cConfirmationEmailSettings\u003e\n{\n\tpublic ConfirmationEmailSettingsValidator()\n\t{\n\t\tRuleFor(x =\u003e x.Subject)\n\t\t\t.NotEmpty()\n\t\t\t.MinimumLength(5);\n\t}\n}\n```\n\n## Use FluentValidation without the source generator\nYou can use FluentValidation without the source generator by not inheriting from `IAppSettings` and using the extension method\n\n```csharp\npublic class ConfirmationEmailSettings\n{\n\tpublic required string Subject { get; set; }\n}\n\nsealed class ConfirmationEmailSettingsValidator : AbstractValidator\u003cConfirmationEmailSettings\u003e\n{\n\tpublic ConfirmationEmailSettingsValidator()\n\t{\n\t\tRuleFor(x =\u003e x.Subject)\n\t\t\t.NotEmpty()\n\t\t\t.MinimumLength(5);\n\t}\n}\n```\nIn your startup -\n```csharp\nservices.AddScoped\u003cIValidator\u003cConfirmationEmailSettings\u003e, ConfirmationEmailSettingsValidator\u003e();\nservices.AddOptions\u003cConfirmationEmailSettings\u003e()\n    .Configure(options =\u003e configuration.GetSection(\"FluentValidationWithValidationButNoSectionNameSettings\").Bind(options))\n    .ValidateFluentValidation()\n    .ValidateOnStart();\n```\n\n# What does the error look like?\nIf something fails validation as the application starts up, you will get an exception explaining the exact issue - \n![image](https://github.com/user-attachments/assets/27465386-3970-49f7-863b-037313f4370f)\n\n# What does the generated code look like?\nThe generated code is just standard C#/ .NET APIs - \n\u003e Left is the AppSettings model, Right is the generated code \n![image](https://github.com/user-attachments/assets/4411edfc-b9e4-4eae-9cd2-c354832965b2)\n\n\n# Considerations\nI do not recommend adding validation to a MAUI project as it can/ will slow startup. To prevent validation, add the `DontValidate` attribute above your class.\n```csharp\n[DontValidate]\npublic class MobileAppSettings : IAppSettings\n{\n\tpublic required string Subject { get; set; }\n}\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fieuanwalker%2Fappsettings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fieuanwalker%2Fappsettings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fieuanwalker%2Fappsettings/lists"}