Skip to content

Commit 32d10ab

Browse files
committed
Parametrizer optimized, custom placeholders fixes
1 parent a39f2fd commit 32d10ab

2 files changed

Lines changed: 49 additions & 13 deletions

File tree

src/ParametrizedConfiguration/Parametrizer.cs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,16 @@ private static IEnumerable<Marker> ScanForPlaceholders(
7474

7575
for (int i = 0; ;)
7676
{
77-
int open = value.IndexOf(parameterPlaceholderOpening, i);
77+
int open = value.IndexOf(parameterPlaceholderOpening, i, StringComparison.Ordinal);
7878
if (open == -1) yield break; // Parameter placeholder opening not found
7979

80-
int close = value.IndexOf(parameterPlaceholderClosing, open + 1);
80+
int close = value.IndexOf(parameterPlaceholderClosing, open + parameterPlaceholderOpening.Length, StringComparison.Ordinal);
8181
if (close == -1) yield break; // Parameter placeholder closing not found
8282

83-
var key = value.Substring(open + 1, close - open - 1);
84-
yield return new Marker(open, close + 1, key);
83+
var key = value.Substring(open + parameterPlaceholderOpening.Length, close - open - parameterPlaceholderOpening.Length);
84+
yield return new Marker(open, close + parameterPlaceholderClosing.Length, key);
8585

86-
i = close + 1;
86+
i = close + parameterPlaceholderClosing.Length;
8787
}
8888
}
8989

@@ -121,8 +121,7 @@ private static IEnumerable<Marker> ScanForPlaceholders(
121121
private static List<string> TopologicalSort(IDictionary<string, List<string>> graph)
122122
{
123123
var ordered = new List<string>(graph.Count);
124-
var visited = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
125-
var visiting = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
124+
var states = new Dictionary<string, NodeState>(graph.Count, StringComparer.OrdinalIgnoreCase);
126125

127126
foreach (var node in graph.Keys)
128127
Dfs(node);
@@ -132,21 +131,36 @@ private static List<string> TopologicalSort(IDictionary<string, List<string>> gr
132131

133132
void Dfs(string node)
134133
{
135-
if (!visiting.Add(node))
136-
throw new CyclicDependencyException(
137-
$"Cyclic dependency detected on parameter '{node}'.");
134+
ref var stateRef = ref CollectionsMarshal.GetValueRefOrAddDefault(states, node, out bool exists);
138135

139-
if (!visited.Add(node))
140-
return;
136+
if (exists)
137+
{
138+
if (stateRef == NodeState.Visiting)
139+
throw new CyclicDependencyException($"Cyclic dependency detected on parameter '{node}'.");
140+
141+
if (stateRef == NodeState.Visited)
142+
return;
143+
}
144+
145+
stateRef = NodeState.Visiting;
141146

142147
if (!graph.TryGetValue(node, out var children))
143148
throw new InvalidOperationException($"Undefined parameter '{node}'.");
144149

145150
foreach (var child in children)
151+
{
146152
Dfs(child);
153+
}
147154

148-
visiting.Remove(node);
155+
stateRef = NodeState.Visited;
149156
ordered.Add(node);
150157
}
151158
}
159+
160+
private enum NodeState : Byte
161+
{
162+
Visiting,
163+
Visited
164+
}
152165
}
166+

test/ConfigurationRepository.UnitTests/ConfigurationParametrizerTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,28 @@ public void Building_Configuration_With_Providers_Succeeds()
132132
CollectionAssert.AreEqual(configuration, dict);
133133
}
134134

135+
136+
[Test]
137+
public void Parametrization_Should_Work_With_Custom_Placehplders()
138+
{
139+
Dictionary<string, string?> configuration = new()
140+
{
141+
{ "parameter", "value" },
142+
{ "Key", "%parameter% ${{parameter}} %parameter%" },
143+
};
144+
145+
var config = new ConfigurationBuilder()
146+
.AddInMemoryCollection(configuration)
147+
.WithParametrization(configureSource =>
148+
{
149+
configureSource.ParameterPlaceholderOpening = "${{";
150+
configureSource.ParameterPlaceholderClosing = "}}";
151+
})
152+
.Build();
153+
154+
Assert.That(config["Key"], Is.EqualTo("%parameter% value %parameter%"));
155+
}
156+
135157
/// <summary>
136158
/// Builds dictionary from <see cref="IConfigurationProvider"/> provider.
137159
/// </summary>

0 commit comments

Comments
 (0)