using System.Collections.Generic; using System.IO; using System.IO.Abstractions; using System.Linq; using Trash.YamlDotNet; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace Trash.Config { public class ConfigurationLoader : IConfigurationLoader where T : BaseConfiguration { private readonly IConfigurationProvider _configProvider; private readonly IDeserializer _deserializer; private readonly IFileSystem _fileSystem; public ConfigurationLoader(IConfigurationProvider configProvider, IFileSystem fileSystem, IObjectFactory objectFactory) { _configProvider = configProvider; _fileSystem = fileSystem; _deserializer = new DeserializerBuilder() .WithNamingConvention(UnderscoredNamingConvention.Instance) // .WithNamingConvention(CamelCaseNamingConvention.Instance) .WithTypeConverter(new YamlNullableEnumTypeConverter()) .WithObjectFactory(objectFactory) .Build(); } public IEnumerable Load(string configPath, string configSection) { using var stream = _fileSystem.File.OpenText(configPath); return LoadFromStream(stream, configSection); } public IEnumerable LoadFromStream(TextReader stream, string configSection) { var parser = new Parser(stream); parser.Consume(); parser.Consume(); parser.Consume(); var configs = new List(); while (parser.TryConsume(out var key)) { if (key.Value == configSection) { configs = _deserializer.Deserialize>(parser); } parser.SkipThisAndNestedEvents(); } if (configs.Count == 0) { throw new ConfigurationException(configSection, typeof(T)); } return configs; } public IEnumerable LoadMany(IEnumerable configFiles, string configSection) { foreach (var config in configFiles.SelectMany(file => Load(file, configSection))) { _configProvider.ActiveConfiguration = config; yield return config; } } } }