Skip to content

Instantly share code, notes, and snippets.

@gimmi
Last active May 25, 2020 15:46
Show Gist options
  • Save gimmi/d9cb5dadb13e9757e95ba3a3af54808d to your computer and use it in GitHub Desktop.
Save gimmi/d9cb5dadb13e9757e95ba3a3af54808d to your computer and use it in GitHub Desktop.
Microsoft.Extensions.Configuration
// var dynamicLoggingConfiguration = new DynamicLoggingConfiguration();
//var hostBuilder = new HostBuilder()
// .ConfigureHostConfiguration(cfg => {
// cfg.Add(dynamicLoggingConfiguration);
// })
namespace MyNs
{
// Inspired by this:
// https://medium.com/@pawel.gerr/asp-net-core-in-production-changing-log-level-temporarily-2nd-approach-5e032b4955ac
public class DynamicLoggingConfiguration : ConfigurationProvider, IConfigurationSource
{
IConfigurationProvider IConfigurationSource.Build(IConfigurationBuilder builder) => this;
public void Apply(AppConfig appCfg)
{
Data[ConfigurationPath.Combine("Logging", "LogLevel", "Default")] = "Warning";
foreach (var (category, logLevel) in appCfg.Logging)
{
var key = ConfigurationPath.Combine("Logging", "LogLevel", category);
Data[key] = logLevel.ToString();
}
OnReload();
}
}
}
// Use like this:
// var hostBuilder = new HostBuilder()
// .ConfigureHostConfiguration(cfg => {
// cfg.Add(new JObjectConfigurationSource(new JObject()));
// })
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
namespace MyNamespace
{
public class JObjectConfigurationSource : ConfigurationProvider, IConfigurationSource
{
private readonly JObject _jObject;
private readonly IDictionary<string, string> _data = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly Stack<string> _context = new Stack<string>();
private string _currentPath;
public JObjectConfigurationSource(JObject jObject) => _jObject = jObject;
public IConfigurationProvider Build(IConfigurationBuilder builder) => this;
public override void Load()
{
Data = ParseStream(_jObject);
}
private IDictionary<string, string> ParseStream(JObject jObject)
{
_data.Clear();
VisitJObject(jObject);
return _data;
}
public void VisitJObject(JObject jObject)
{
foreach (var property in jObject.Properties())
{
EnterContext(property.Name);
VisitProperty(property);
ExitContext();
}
}
private void VisitProperty(JProperty property)
{
VisitToken(property.Value);
}
private void VisitToken(JToken token)
{
switch (token.Type)
{
case JTokenType.Object:
VisitJObject(token.Value<JObject>());
break;
case JTokenType.Array:
VisitArray(token.Value<JArray>());
break;
case JTokenType.Integer:
case JTokenType.Float:
case JTokenType.String:
case JTokenType.Boolean:
case JTokenType.Null:
case JTokenType.Raw:
case JTokenType.Bytes:
VisitPrimitive(token.Value<JValue>());
break;
default:
throw new FormatException();
}
}
private void VisitArray(JArray array)
{
for (int index = 0; index < array.Count; ++index)
{
EnterContext(index.ToString());
VisitToken(array[index]);
ExitContext();
}
}
private void VisitPrimitive(JValue data)
{
string currentPath = _currentPath;
if (_data.ContainsKey(currentPath))
{
throw new FormatException();
}
_data[currentPath] = data.ToString(CultureInfo.InvariantCulture);
}
private void EnterContext(string context)
{
_context.Push(context);
_currentPath = ConfigurationPath.Combine(_context.Reverse());
}
private void ExitContext()
{
_context.Pop();
_currentPath = ConfigurationPath.Combine(_context.Reverse());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment