-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathExpandWrapper.cs
67 lines (56 loc) · 2.93 KB
/
ExpandWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Xml;
using Microsoft.Configuration.ConfigurationBuilders;
namespace SamplesLib
{
public class ExpandWrapper<T> : ConfigurationBuilder where T : KeyValueConfigBuilder, new()
{
private static MethodInfo _expandTokensMethod = typeof(KeyValueConfigBuilder).GetMethod("ExpandTokens", BindingFlags.NonPublic | BindingFlags.Instance);
private T _underlyingBuilder;
public ExpandWrapper() { _underlyingBuilder = new T(); }
public override void Initialize(string name, NameValueCollection config) => _underlyingBuilder.Initialize(name, config);
public override XmlNode ProcessRawXml(XmlNode rawXml)
{
rawXml = _underlyingBuilder.ProcessRawXml(rawXml);
// !!!DO NOT APPLY TO APPSETTINGS!!!
// AppSettings is special because it can be implicitly referenced when looking for config builder
// settings, while it can simultaneously be processed by config builders. There used to be special
// logic to help manage potential recursion in the base KeyValueConfigBuilder class, but that
// protection is no more since 'Expand' mode and the use of _both_ ProcessRawXml() and ProcessConfigSection()
// have been removed.
if (rawXml.Name != "appSettings") // System.Configuration hard codes this, so we might as well too.
{
// Checking Enabled will kick off LazyInit, so only do that if we are actually going to do work here.
if (_underlyingBuilder.Mode == KeyValueMode.Token && _underlyingBuilder.Enabled != KeyValueEnabled.Disabled)
{
// Old Expand-mode would do a recursion check here. We don't have internal access to RecursionGuard.
return ExpandTokens(rawXml);
}
}
return rawXml;
}
public override ConfigurationSection ProcessConfigurationSection(ConfigurationSection configSection)
{
// We have overridden the meaning of "Token" mode for this class. Don't do any processing in that mode.
if (_underlyingBuilder.Mode == KeyValueMode.Token)
return configSection;
return _underlyingBuilder.ProcessConfigurationSection(configSection);
}
private XmlNode ExpandTokens(XmlNode rawXml)
{
string rawXmlString = rawXml.OuterXml;
if (String.IsNullOrEmpty(rawXmlString))
return rawXml;
string updatedXmlString = (string)_expandTokensMethod.Invoke(_underlyingBuilder, new object[] { rawXmlString });
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(updatedXmlString);
return doc.DocumentElement;
}
}
}