private void SubstVars(VarsContainer vars, XElement elem)
        {
            var texts =
                elem
                .DescendantNodesAndSelf()
                .OfType <XText>();

            foreach (var text in texts)
            {
                text.Value = SubstVars(vars, text.Value);
            }
            foreach (var attr in elem.DescendantsAndSelf().Attributes())
            {
                attr.Value = SubstVars(vars, attr.Value);
            }
        }
        private void LoadSections(IConfigDataProvider provider, VarsContainer parentVars)
        {
            if (_providers.Contains(provider))
            {
                throw new ApplicationException("Circular reference was found for '" + provider + "'");
            }

            XDocument xDoc;

            using (var reader = provider.ReadData())
                xDoc = XDocument.Load(reader);

            var includes = new List <string>();
            var varsDic  = new Dictionary <string, string>();
            var sections = new List <XElement>();

            if (xDoc.Root != null)
            {
                foreach (var elem in xDoc.Root.Elements())
                {
                    if (elem.Name.NamespaceName == ConfigXmlConstants.XmlNamespace)
                    {
                        switch (elem.Name.LocalName)
                        {
                        case ConfigXmlConstants.IncludeTagName:
                        {
                            var trimmed = elem.Value;
                            if (trimmed == "")
                            {
                                throw new ConfigurationException(ConfigurationResources.IncludeEmptyMessage);
                            }
                            includes.Add(trimmed);
                            continue;
                        }

                        case ConfigXmlConstants.VariableTagName:
                        {
                            var name = elem.Attribute(ConfigXmlConstants.VariableNameAttribute);
                            if (name == null || name.Value == "")
                            {
                                throw new ConfigurationException(ConfigurationResources.VarNameEmptyMessage);
                            }
                            if (varsDic.ContainsKey(name.Value) || parentVars.IsVarDefined(name.Value))
                            {
                                throw new ConfigurationException(
                                          string.Format(ConfigurationResources.VarAlreadyDefined, name));
                            }
                            varsDic.Add(name.Value, SubstVars(varsDic, elem.Value.Trim()));
                            continue;
                        }
                        }
                    }
                    sections.Add(elem);
                }
            }

            var vars = new VarsContainer(varsDic, parentVars);

            foreach (var elem in sections)
            {
                SubstVars(vars, elem);
                var secName = SectionName.Create(elem);
                if (_loadedSections.ContainsKey(secName))
                {
                    _loadedSections[secName].Add(elem);
                }
                else
                {
                    _loadedSections.Add(secName, new List <XElement>(new[] { elem }));
                }
            }

            foreach (var include in includes)
            {
                LoadSections(provider.ResolveInclude(include), vars);
            }

            _providers.Add(provider);
            provider.ConfigChanged += ProviderConfigChanged;
        }
 public ConfigSerializer(IConfigDataProvider dataProvider,
                         IDictionary <string, string> rootVars)
 {
     _dataProvider = dataProvider;
     _rootVars     = new VarsContainer(rootVars);
 }
 private string SubstVars(VarsContainer vars, string str)
 {
     return(_varsRegex.Replace(str,
                               match => vars.GetVar(match.Groups[1].Value)));
 }
 public VarsContainer(IDictionary <string, string> varsDic, VarsContainer parent = null)
 {
     _varsDic = varsDic;
     _parent  = parent;
 }