using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; namespace ZeroLevel.Services.Config.Implementation { internal sealed class AppWebConfigReader { private readonly string _configFilePath; public bool ExistsAppConfigFile => string.IsNullOrWhiteSpace(_configFilePath) == false; internal AppWebConfigReader(string configFilePath = null!) { if (configFilePath == null) { var appConfig = Path.Combine(Configuration.BaseDirectory, $"{System.AppDomain.CurrentDomain.FriendlyName}.config"); if (File.Exists(appConfig)) { _configFilePath = appConfig; } else { var webConfig = Path.Combine(Configuration.BaseDirectory, "web.config"); if (File.Exists(webConfig)) { _configFilePath = webConfig; } else { _configFilePath = Directory.GetFiles(Configuration.BaseDirectory, "*.config").FirstOrDefault(); } } } else { if (configFilePath.IndexOf(':') < 0) { this._configFilePath = Path.Combine(Configuration.BaseDirectory, configFilePath); } else { this._configFilePath = configFilePath; } } } internal IEnumerable GetSections() { if (_configFilePath != null) { var xdoc = XDocument.Load(_configFilePath); var cs = xdoc.Descendants("connectionStrings"). Select(x => x.Name.LocalName); return xdoc.Descendants("section") .Select(x => x.Attribute("name").Value).Union(cs); } return Enumerable.Empty(); } internal IEnumerable> ReadSection(string sectionName) { if (_configFilePath != null) { var xdoc = XDocument.Load(_configFilePath); return xdoc.Descendants(sectionName). SelectMany(x => x.Nodes().Where(n => null != (n as XElement)).Select(n => { var xe = n as XElement; return new Tuple(FindName(xe!), FindValue(xe!)); })) .Where(t => string.IsNullOrWhiteSpace(t.Item1) == false); } return Enumerable.Empty>(); } private static string FindName(XElement n) { if (n == null) return string.Empty; var attributes = n.Attributes(). ToDictionary(i => i.Name.LocalName.ToLowerInvariant(), j => j.Value); foreach (var v in new[] { "key", "name", "code", "id" }) { if (attributes.ContainsKey(v)) return attributes[v]; } return n.Name.LocalName; } private static string FindValue(XElement n) { if (n == null) return string.Empty; var attributes = n.Attributes(). ToDictionary(i => i.Name.LocalName.ToLowerInvariant(), j => j.Value); foreach (var v in new[] { "value", "val", "file", "db", "connectionstring" }) { if (attributes.ContainsKey(v)) return attributes[v]; } return n.Value; } internal IEnumerable> ReadAppSettings() { return ReadSection("appSettings"); } } }