Last active
November 22, 2024 08:09
-
-
Save unseensenpai/a16e7f076dec0e91459e8b3e67a5fc8b to your computer and use it in GitHub Desktop.
How To Register App.Config and appsettings.json -> Config Manager for .Net 6+ and ASP.NET Core 6+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<configuration> | |
<appSettings> | |
<add key="Bla:Foo:Zoo" value="SampleValue" /> | |
</appSettings> | |
</configuration> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"ConnectionStrings": { | |
"Default": "123456" | |
}, | |
"SampleInt": 1234567, | |
"SampleStringInt": "1234567" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ApiController] | |
[Route("[Controller]/[Action]")] | |
public class ConfigController : Controller | |
{ | |
[HttpGet] | |
public IList<ConfigKeyValue> GetConfigs() | |
{ | |
// HOW TO READ CONFIGS ON ASP.NET CORE WEB API (IT HAS OWN DI BUT SOME REASON ITS USABLE FOR IT THO) | |
return ConfigManager.ConfigurationKeyValues.ToList(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Static config manager instance. | |
/// It uses the Microsoft Extensions Configuration engine. | |
/// It includes methods to access key values in | |
/// App.config in .Net Framework and appsettings.json in .Net 5+. | |
/// <para> | |
/// How To Set: | |
/// </para> | |
/// <code> | |
/// ConfigManager.SetConfiguration( | |
/// configFilePaths: [ | |
/// new(JsonPath: "appsettings.json", Optional: false, ReloadOnChange: true), | |
/// new(JsonPath: "config/appsettings.json", Optional: true, ReloadOnChange: true) | |
/// ], | |
/// nameValueCollections: | |
/// [ | |
/// System.Configuration.ConfigurationManager.AppSettings, | |
/// new System.Collections.Specialized.NameValueCollection() { { "Key1", "true" }, { "Key2", "password123" } } | |
/// ] | |
/// ); | |
/// </code> | |
/// Usage: | |
/// <para> | |
/// <code> | |
/// ConfigManager.Configuration.GetValue("KEYOFCONFIGVALUE"); | |
/// </code> | |
/// </para> | |
/// </summary> | |
public static class ConfigManager | |
{ | |
/// <summary> | |
/// Static configuration instance. Use the <seealso cref="SetConfiguration"></seealso> method to set it. | |
/// </summary> | |
public static IConfiguration Configuration { get; private set; } | |
/// <summary> | |
/// Retrieves previously set config key values with child node(s) if exist as enumerable. | |
/// </summary> | |
public static IEnumerable<ConfigKeyValue> ConfigurationKeyValues | |
{ | |
get => | |
IsConfigManagerSet | |
? Configuration.AsEnumerable().Select(cfg => new ConfigKeyValue(cfg.Key, cfg.Value)) | |
#if NET8_0_OR_GREATER | |
: []; | |
#elif NET6_0 || NET7_0 | |
: Enumerable.Empty<ConfigKeyValue>(); | |
#endif | |
} | |
/// <summary> | |
/// Retrieves previously set config key values pairs with child node(s) if exist as enumerable. | |
/// </summary> | |
public static IEnumerable<KeyValuePair<string, string>> ConfigurationKeyValuePairs | |
{ | |
get => | |
IsConfigManagerSet | |
? Configuration.AsEnumerable().Select(cfg => new KeyValuePair<string, string>(cfg.Key, cfg.Value)) | |
#if NET8_0_OR_GREATER | |
: []; | |
#elif NET6_0 || NET7_0 | |
: Enumerable.Empty<KeyValuePair<string, string>>(); | |
#endif | |
} | |
/// <summary> | |
/// Serilog KeyValue Pairs | |
/// </summary> | |
public static IEnumerable<KeyValuePair<string, string>> GetSerilogKeyValuePairs | |
{ | |
get => GetKeyValuePairs("serilog:", true); | |
} | |
/// <summary> | |
/// Gets specific config key values via prefix | |
/// </summary> | |
/// <param name="configPrefix"></param> | |
/// <param name="erasePrefixFromKeys">Erased prefix value from keys if true. | |
/// <para> | |
/// <code> | |
/// Key: Serilog:WriteTo - Value: File -> | |
/// <para> | |
/// Prefix Serilog -> | |
/// <para> | |
/// Key: WriteTo - Value: File | |
/// </para> | |
/// </para> | |
/// </code> | |
/// </para> | |
/// </param> | |
/// <returns></returns> | |
public static IEnumerable<KeyValuePair<string, string>> GetKeyValuePairs(string configPrefix, bool erasePrefixFromKeys) | |
{ | |
if (erasePrefixFromKeys) | |
{ | |
return ConfigurationKeyValues | |
.Where(k => | |
k.Key.StartsWith(configPrefix)) | |
.Select(k => | |
new KeyValuePair<string, string>( | |
k.Key[configPrefix.Length..], | |
k.Value)); | |
} | |
else | |
{ | |
return ConfigurationKeyValues | |
.Where(k => | |
k.Key.StartsWith(configPrefix)) | |
.Select(k => | |
new KeyValuePair<string, string>( | |
k.Key, | |
k.Value)); | |
} | |
} | |
/// <summary> | |
/// Checks Configuration Set State. | |
/// </summary> | |
public static bool IsConfigManagerSet { get => Configuration is not null; } | |
/// <summary> | |
/// Throws <see cref="ConfigurationNotSetException"/> if config manager is not set. | |
/// </summary> | |
/// <exception cref="ConfigurationNotSetException">Config Manager Is Not Set Exception</exception> | |
public static void ThrowIfConfigManagerNotSet() | |
{ | |
if (!IsConfigManagerSet) | |
throw new ConfigurationNotSetException("Config Manager Is Not Set! Use: ConfigManager.SetConfiguration()"); | |
} | |
/// <summary> | |
/// Creates <seealso cref="IConfiguration"/> instance. | |
/// </summary> | |
/// <param name="configFilePaths">Json configs (appsettings.json)</param> | |
/// <param name="nameValueCollections">Xml configs (App.config)</param> | |
/// <returns></returns> | |
public static IConfiguration CreateConfiguration(List<JsonConfigSettings> configFilePaths = default, List<NameValueCollection> nameValueCollections = default) | |
{ | |
ConfigurationBuilder configBuilder = new(); | |
// APPSETTINGS.JSON | |
if (configFilePaths is not null && configFilePaths.Count > 0) | |
{ | |
foreach (JsonConfigSettings configFilePath in configFilePaths) | |
{ | |
configBuilder.AddJsonFile( | |
path: configFilePath.JsonPath, | |
optional: configFilePath.Optional, | |
reloadOnChange: configFilePath.ReloadOnChange); | |
} | |
} | |
// APP.CONFIG | |
if (nameValueCollections is not null && nameValueCollections.Count > 0) | |
{ | |
foreach (NameValueCollection nameValueCollection in nameValueCollections) | |
{ | |
Dictionary<string, string> keyValues = nameValueCollection.AllKeys.ToDictionary(key => key, key => nameValueCollection[key]); | |
configBuilder.AddInMemoryCollection(keyValues); | |
} | |
} | |
return configBuilder.Build(); | |
} | |
/// <summary> | |
/// Sets <seealso cref="Configuration"></seealso> instance. | |
/// </summary> | |
/// <param name="configFilePaths">Json configs (appsettings.json)</param> | |
/// <param name="nameValueCollections">Xml configs (App.config)</param> | |
/// <returns></returns> | |
public static void SetConfiguration(List<JsonConfigSettings> configFilePaths = default, List<NameValueCollection> nameValueCollections = default) | |
{ | |
ConfigurationBuilder configBuilder = new(); | |
// APPSETTINGS.JSON | |
if (configFilePaths is not null && configFilePaths.Count > 0) | |
{ | |
foreach (JsonConfigSettings configFilePath in configFilePaths) | |
{ | |
configBuilder.AddJsonFile( | |
path: configFilePath.JsonPath, | |
optional: configFilePath.Optional, | |
reloadOnChange: configFilePath.ReloadOnChange); | |
} | |
} | |
// APP.CONFIG | |
if (nameValueCollections is not null && nameValueCollections.Count > 0) | |
{ | |
foreach (NameValueCollection nameValueCollection in nameValueCollections) | |
{ | |
Dictionary<string, string> keyValues = nameValueCollection.AllKeys.ToDictionary(key => key, key => nameValueCollection[key]); | |
configBuilder.AddInMemoryCollection(keyValues); | |
} | |
} | |
Configuration = configBuilder.Build(); | |
} | |
// TODO Refresh Mechanism see FileSystemWatcher | |
} | |
/// <summary> | |
/// Json file settings object for configuration operations. | |
/// </summary> | |
/// <param name="JsonPath">Json config file path with filename</param> | |
/// <param name="Optional">Is config file optional (If false it throws an error if there is no file in "JsonPath")</param> | |
/// <param name="ReloadOnChange">Is reload on change</param> | |
public record JsonConfigSettings(string JsonPath, bool Optional = false, bool ReloadOnChange = true); | |
/// <summary> | |
/// Config key value object. | |
/// </summary> | |
/// <param name="Key">Config Key</param> | |
/// <param name="Value">Config Value</param> | |
public record ConfigKeyValue(string Key, string Value); | |
/// <summary> | |
/// ConfigManager configuration not set exception class. <seealso cref="ConfigManager.SetConfiguration(List{JsonConfigSettings}, List{NameValueCollection})"/> | |
/// </summary> | |
public class ConfigurationNotSetException : Exception | |
{ | |
/// <summary> | |
/// Default constructor without message or inner exception. | |
/// </summary> | |
public ConfigurationNotSetException() | |
{ | |
} | |
/// <summary> | |
/// Exception with message. | |
/// </summary> | |
/// <param name="message">Error Message</param> | |
public ConfigurationNotSetException(string message) : base(message) | |
{ | |
} | |
/// <summary> | |
/// Exception with message and inner exception. | |
/// </summary> | |
/// <param name="message">Error Message</param> | |
/// <param name="innerException">Inner Exception</param> | |
public ConfigurationNotSetException(string message, Exception innerException) : base(message, innerException) | |
{ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var builder = WebApplication.CreateBuilder(args); | |
// HOW TO REGISTER ALL CONFIGS TO ASP.NET CORE DI (EITHER APP.CONFIG or APPSETTINGS.JSON) | |
ConfigManager.SetConfiguration([new("appsettings.json", true, true), new("appsettings.development.json", true, true)]) | |
builder.Configuration.AddInMemoryCollection(ConfigManager.ConfigurationKeyValues.Select(cm => new KeyValuePair<string, string>(cm.Key, cm.Value))); | |
var app = builder.Build(); | |
app.Run(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// The main entry point for the application. | |
/// </summary> | |
[STAThread] | |
static void Main() | |
{ | |
List<ConfigFilePaths> configFilePaths = [ | |
new ConfigFilePaths("appsettings.json", true), | |
new ConfigFilePaths("Config/appsettings.json"), | |
new ConfigFilePaths($"appsettings.development.json", true) | |
]; | |
List<NameValueCollection> nameValueCollections = [System.Configuration.ConfigurationManager.AppSettings]; | |
ConfigManager.SetConfiguration(configFilePaths, nameValueCollections); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public WinFormUsage() | |
{ | |
InitializeComponent(); | |
// SOME USE CASES ON WINFORM FORMS | |
gridControl1.DataSource = ConfigManager.ConfigurationKeyValues; | |
string connString = ConfigManager.Configuration.GetConnectionString("Default"); | |
int sampleInt = Convert.ToInt32(ConfigManager.Configuration["SampleInt"]); | |
int sampleIntWithGetValue = ConfigManager.Configuration.GetValue<int>("SampleInt"); | |
int sampleInt2 = ConfigManager.Configuration.GetValue<int>("SampleStringInt"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment