diff --git a/src/Winton.Extensions.Configuration.Consul/Extensions/ConfigurationbuilderExtensions.cs b/src/Winton.Extensions.Configuration.Consul/Extensions/ConfigurationbuilderExtensions.cs
new file mode 100644
index 0000000..231701c
--- /dev/null
+++ b/src/Winton.Extensions.Configuration.Consul/Extensions/ConfigurationbuilderExtensions.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Winton. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System;
+using System.IO;
+using Microsoft.Extensions.Configuration;
+using Winton.Extensions.Configuration.Consul.Internals;
+
+namespace Winton.Extensions.Configuration.Consul.Extensions
+{
+ ///
+ /// Extra Extesntions for Json Array Parsing.
+ ///
+ public static class ConfigurationbuilderExtensions
+ {
+ ///
+ /// Adds a JSON Array configuration source to .
+ ///
+ /// The to add to.
+ /// The to read the json configuration data from.
+ /// The .
+ public static IConfigurationBuilder AddJsonArrayStream(this IConfigurationBuilder builder, Stream stream)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ return builder.Add(s => s.Stream = stream);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Winton.Extensions.Configuration.Consul/Extensions/KVPairQueryResultExtensions.cs b/src/Winton.Extensions.Configuration.Consul/Extensions/KVPairQueryResultExtensions.cs
index c95d69a..7e0e955 100644
--- a/src/Winton.Extensions.Configuration.Consul/Extensions/KVPairQueryResultExtensions.cs
+++ b/src/Winton.Extensions.Configuration.Consul/Extensions/KVPairQueryResultExtensions.cs
@@ -6,7 +6,6 @@
using System.Linq;
using System.Net;
using Consul;
-using Winton.Extensions.Configuration.Consul.Parsers;
namespace Winton.Extensions.Configuration.Consul.Extensions
{
diff --git a/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationProvider.cs b/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationProvider.cs
new file mode 100644
index 0000000..b634667
--- /dev/null
+++ b/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationProvider.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Winton. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System.IO;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Json;
+
+namespace Winton.Extensions.Configuration.Consul.Internals
+{
+ internal sealed class JsonArrayStreamConfigurationProvider : StreamConfigurationProvider
+ {
+ public JsonArrayStreamConfigurationProvider(JsonArrayStreamConfigurationSource source)
+ : base(source)
+ {
+ }
+
+ ///
+ ///
+ /// Loads json configuration key/values from a stream into a provider.
+ ///
+ /// The json to load configuration data from.
+ public override void Load(Stream stream)
+ {
+ Data = JsonConfigurationFileParser.Parse(stream);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationSource.cs b/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationSource.cs
new file mode 100644
index 0000000..6a4872f
--- /dev/null
+++ b/src/Winton.Extensions.Configuration.Consul/Internals/JsonArrayStreamConfigurationSource.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Winton. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Json;
+
+namespace Winton.Extensions.Configuration.Consul.Internals
+{
+ ///
+ /// Json Array Variant of Config Provider.
+ ///
+ public class JsonArrayStreamConfigurationSource : StreamConfigurationSource
+ {
+ ///
+ /// Builds the for this source.
+ ///
+ /// The .
+ /// An .
+ public override IConfigurationProvider Build(IConfigurationBuilder builder)
+ => new JsonArrayStreamConfigurationProvider(this);
+ }
+}
\ No newline at end of file
diff --git a/src/Winton.Extensions.Configuration.Consul/Internals/JsonConfigurationFileParser.cs b/src/Winton.Extensions.Configuration.Consul/Internals/JsonConfigurationFileParser.cs
new file mode 100644
index 0000000..4b119c9
--- /dev/null
+++ b/src/Winton.Extensions.Configuration.Consul/Internals/JsonConfigurationFileParser.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Winton. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+using Microsoft.Extensions.Configuration;
+
+namespace Winton.Extensions.Configuration.Consul.Internals
+{
+ internal class JsonConfigurationFileParser
+ {
+ private readonly IDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase);
+ private readonly Stack _context = new Stack();
+ private string? _currentPath;
+ private string? _dataPrefix;
+
+ private JsonConfigurationFileParser(string? prefix = null)
+ {
+ _dataPrefix = prefix;
+ }
+
+ public static IDictionary Parse(Stream input)
+ => new JsonConfigurationFileParser().ParseStream(input);
+
+ private IDictionary ParseStream(Stream input)
+ {
+ _data.Clear();
+
+ var jsonDocumentOptions = new JsonDocumentOptions
+ {
+ CommentHandling = JsonCommentHandling.Skip,
+ AllowTrailingCommas = true,
+ };
+
+ using (var reader = new StreamReader(input))
+ using (JsonDocument doc = JsonDocument.Parse(reader.ReadToEnd(), jsonDocumentOptions))
+ {
+ if (doc.RootElement.ValueKind != JsonValueKind.Object && doc.RootElement.ValueKind != JsonValueKind.Array)
+ {
+ throw new FormatException(/*Resources.FormatError_UnsupportedJSONToken(doc.RootElement.ValueKind)*/);
+ }
+
+ switch (doc.RootElement.ValueKind)
+ {
+ case JsonValueKind.Object:
+ VisitElement(doc.RootElement);
+ break;
+ case JsonValueKind.Array:
+ VisitArrayElement(doc.RootElement);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ return _data;
+ }
+
+ private void VisitElement(JsonElement element)
+ {
+ foreach (var property in element.EnumerateObject())
+ {
+ EnterContext(property.Name);
+ VisitValue(property.Value);
+ ExitContext();
+ }
+ }
+
+ private void VisitArrayElement(JsonElement element)
+ {
+ var prefixIdx = 0;
+ foreach (var arrayElement in element.EnumerateArray())
+ {
+ switch (arrayElement.ValueKind)
+ {
+ case JsonValueKind.Number:
+ case JsonValueKind.String:
+ case JsonValueKind.True:
+ case JsonValueKind.False:
+ case JsonValueKind.Null:
+ EnterContext($"{(_dataPrefix is null ? $"{prefixIdx}" : $"{_dataPrefix}:{prefixIdx}")}");
+ VisitValue(arrayElement);
+ ExitContext();
+ break;
+ case JsonValueKind.Object:
+ foreach (var property in arrayElement.EnumerateObject())
+ {
+ EnterContext($"{(_dataPrefix is null ? $"{prefixIdx}:" : $"{_dataPrefix}:{prefixIdx}:")}{property.Name}");
+ VisitValue(property.Value);
+ ExitContext();
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+
+ prefixIdx++;
+ }
+ }
+
+ private void VisitValue(JsonElement value)
+ {
+ switch (value.ValueKind)
+ {
+ case JsonValueKind.Object:
+ VisitElement(value);
+ break;
+
+ case JsonValueKind.Array:
+ var index = 0;
+ foreach (var arrayElement in value.EnumerateArray())
+ {
+ EnterContext(index.ToString());
+ VisitValue(arrayElement);
+ ExitContext();
+ index++;
+ }
+
+ break;
+
+ case JsonValueKind.Number:
+ case JsonValueKind.String:
+ case JsonValueKind.True:
+ case JsonValueKind.False:
+ case JsonValueKind.Null:
+ var key = _currentPath;
+ if (_data.ContainsKey(key ?? string.Empty))
+ {
+ throw new FormatException(/*Resources.FormatError_KeyIsDuplicated(key)*/);
+ }
+
+ _data[key ?? string.Empty] = value.ToString();
+ break;
+
+ default:
+ throw new FormatException(/*Resources.FormatError_UnsupportedJSONToken(value.ValueKind)*/);
+ }
+ }
+
+ private void EnterContext(string context)
+ {
+ _context.Push(context);
+ _currentPath = ConfigurationPath.Combine(_context.Reverse());
+ }
+
+ private void ExitContext()
+ {
+ _context.Pop();
+ _currentPath = ConfigurationPath.Combine(_context.Reverse());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Winton.Extensions.Configuration.Consul/Parsers/JsonConfigurationParser.cs b/src/Winton.Extensions.Configuration.Consul/Parsers/JsonConfigurationParser.cs
index 4a4cea0..4f15b19 100644
--- a/src/Winton.Extensions.Configuration.Consul/Parsers/JsonConfigurationParser.cs
+++ b/src/Winton.Extensions.Configuration.Consul/Parsers/JsonConfigurationParser.cs
@@ -5,6 +5,7 @@
using System.IO;
using System.Linq;
using Microsoft.Extensions.Configuration;
+using Winton.Extensions.Configuration.Consul.Extensions;
namespace Winton.Extensions.Configuration.Consul.Parsers
{
@@ -18,7 +19,7 @@ public sealed class JsonConfigurationParser : IConfigurationParser
public IDictionary Parse(Stream stream)
{
return new ConfigurationBuilder()
- .AddJsonStream(stream)
+ .AddJsonArrayStream(stream)
.Build()
.AsEnumerable()
.ToDictionary(pair => pair.Key, pair => pair.Value);
diff --git a/src/Winton.Extensions.Configuration.Consul/Winton.Extensions.Configuration.Consul.csproj b/src/Winton.Extensions.Configuration.Consul/Winton.Extensions.Configuration.Consul.csproj
index 0f60720..17d2f42 100644
--- a/src/Winton.Extensions.Configuration.Consul/Winton.Extensions.Configuration.Consul.csproj
+++ b/src/Winton.Extensions.Configuration.Consul/Winton.Extensions.Configuration.Consul.csproj
@@ -27,9 +27,9 @@
-
-
-
+
+
+