| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- using Microsoft.Extensions.Configuration;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- namespace Porta.Kundenzähler.Services.Extension
- {
- public static class ConfigurationExtension
- {
- #region Configuration reading
- /// <summary>
- /// Read a section of the configuration and bind it to a corresponding object containing the same properties (Names must match)
- /// </summary>
- /// <typeparam name="T">The type of the config section object.</typeparam>
- /// <param name="configuration">The full configuration.</param>
- /// <param name="key">The key of the section.</param>
- /// <returns>The config section object.</returns>
- public static T GetSection<T>(this IConfiguration configuration, string key)
- {
- if (String.IsNullOrEmpty(key))
- throw new ArgumentException("The section key must not be NULL or empty.", key);
- // Create empty instance of config object type
- var optionsObj = Activator.CreateInstance<T>();
- var section = configuration.GetSection(key);
- if (section == null)
- throw new ArgumentException("The requested section cannot be found in configuration file.", key);
- // Map the object properties to the section properties
- MapSectionPropertiesToObject(configuration, optionsObj, section);
- return optionsObj;
- }
- /// <summary>
- /// Map the properties of a configuration object to the corresponding properties in the configuration section
- /// </summary>
- /// <param name="configuration">The full configuration.</param>
- /// <param name="optionsObj">The current options object.</param>
- /// <param name="currentSection">The current processing section.</param>
- private static void MapSectionPropertiesToObject(IConfiguration configuration, object optionsObj,
- IConfigurationSection currentSection)
- {
- // Get all options object properties
- var properties = optionsObj.GetType().GetProperties();
- foreach (var propertyInfo in properties)
- {
- // Check non primitive, not value typed, only classed properties
- if (propertyInfo.PropertyType.IsClass
- && !propertyInfo.PropertyType.IsArray
- && !propertyInfo.PropertyType.IsValueType
- && !propertyInfo.PropertyType.IsPrimitive
- && propertyInfo.PropertyType.FullName != "System.String")
- {
- // Get the section configuration value of the current property
- var valueObj = currentSection.GetValue<object>(propertyInfo.Name);
- // Proceed when value object can be created
- if (valueObj != null)
- {
- // If the property is NULL, create an object for the property
- if (propertyInfo.GetValue(optionsObj) == null)
- propertyInfo.SetValue(optionsObj, Activator.CreateInstance(propertyInfo.PropertyType));
- // Recursive call
- MapSectionPropertiesToObject(configuration, propertyInfo.GetValue(optionsObj),
- currentSection.GetSection(propertyInfo.Name));
- }
- }
- else
- {
- // Read the value from the current section
- var valueObj = currentSection.GetValue<object>(propertyInfo.Name);
- // If the value object is NULL then it might not be set or cannot be evaluated
- if (valueObj != null)
- {
- // Serialize the value as a JSON string
- var jsonStr = JsonConvert.SerializeObject(valueObj);
- // Deserialize from the JSON string to prevent conversion issues
- var value = JsonConvert.DeserializeObject(jsonStr, propertyInfo.PropertyType);
- propertyInfo.SetValue(optionsObj, value);
- }
- }
- }
- }
- #endregion
- }
- }
|