diff --git a/src/Hocon.Extensions.Configuration.Tests/IncludeTest.cs b/src/Hocon.Extensions.Configuration.Tests/IncludeTest.cs
new file mode 100644
index 0000000..7e11a89
--- /dev/null
+++ b/src/Hocon.Extensions.Configuration.Tests/IncludeTest.cs
@@ -0,0 +1,33 @@
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Xunit;
+
+namespace Hocon.Extensions.Configuration.Tests
+{
+ public class IncludeTest
+ {
+ [Fact]
+ public void ProcessIncludes()
+ {
+ var hocon = @"{
+ servers { include file(""servers.hocon"") }
+ }";
+
+ var hoconConfigSource = new HoconConfigurationSource
+ {
+ FileProvider = TestStreamHelpers.StringToFileProvider(hocon),
+ IncludeCallback = (type, value) => Task.FromResult(@"{
+ server1 = 10.0.0.1
+ server2 = 10.0.0.2
+}")
+ };
+
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.Add(hoconConfigSource);
+ var config = configurationBuilder.Build();
+
+ Assert.Equal("10.0.0.1", config["servers:server1"]);
+ Assert.Equal("10.0.0.2", config["servers:server2"]);
+ }
+ }
+}
diff --git a/src/Hocon.Extensions.Configuration/HoconConfigurationExtensions.cs b/src/Hocon.Extensions.Configuration/HoconConfigurationExtensions.cs
index 654b516..6c6288b 100644
--- a/src/Hocon.Extensions.Configuration/HoconConfigurationExtensions.cs
+++ b/src/Hocon.Extensions.Configuration/HoconConfigurationExtensions.cs
@@ -72,9 +72,10 @@ public static IConfigurationBuilder AddHoconFile(this IConfigurationBuilder buil
///
/// Whether the file is optional.
/// Whether the configuration should be reloaded if the file changes.
+ /// Include callback.
/// The .
public static IConfigurationBuilder AddHoconFile(this IConfigurationBuilder builder, IFileProvider provider,
- string path, bool optional, bool reloadOnChange)
+ string path, bool optional, bool reloadOnChange, HoconIncludeCallbackAsync includeCallback = null)
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
if (string.IsNullOrEmpty(path)) throw new ArgumentException(Resources.Error_InvalidFilePath, nameof(path));
@@ -85,6 +86,7 @@ public static IConfigurationBuilder AddHoconFile(this IConfigurationBuilder buil
s.Path = path;
s.Optional = optional;
s.ReloadOnChange = reloadOnChange;
+ s.IncludeCallback = includeCallback;
s.ResolveFileProvider();
});
}
diff --git a/src/Hocon.Extensions.Configuration/HoconConfigurationFileParser.cs b/src/Hocon.Extensions.Configuration/HoconConfigurationFileParser.cs
index c0bef12..a13d8b2 100644
--- a/src/Hocon.Extensions.Configuration/HoconConfigurationFileParser.cs
+++ b/src/Hocon.Extensions.Configuration/HoconConfigurationFileParser.cs
@@ -19,8 +19,16 @@ internal class HoconConfigurationFileParser
private readonly IDictionary _data =
new SortedDictionary(StringComparer.OrdinalIgnoreCase);
+ private readonly HoconIncludeCallbackAsync _includeCallback;
+
private string _currentPath;
+
+ public HoconConfigurationFileParser(HoconIncludeCallbackAsync includeCallback)
+ {
+ _includeCallback = includeCallback;
+ }
+
public IDictionary Parse(Stream input)
{
_data.Clear();
@@ -28,7 +36,7 @@ public IDictionary Parse(Stream input)
using (var textStream = new StreamReader(input))
{
var content = textStream.ReadToEnd();
- var hoconConfig = HoconParser.Parse(content);
+ var hoconConfig = HoconParser.Parse(content, _includeCallback ?? HoconConfigurationSource.DefaultIncludeCallback);
VisitHoconObject(hoconConfig.Value.GetObject());
}
diff --git a/src/Hocon.Extensions.Configuration/HoconConfigurationProvider.cs b/src/Hocon.Extensions.Configuration/HoconConfigurationProvider.cs
index da073a0..64f7076 100644
--- a/src/Hocon.Extensions.Configuration/HoconConfigurationProvider.cs
+++ b/src/Hocon.Extensions.Configuration/HoconConfigurationProvider.cs
@@ -17,12 +17,15 @@ namespace Hocon.Extensions.Configuration
///
public class HoconConfigurationProvider : FileConfigurationProvider
{
+ private readonly HoconConfigurationSource _source;
+
///
/// Initializes a new instance with the specified source.
///
/// The source settings.
public HoconConfigurationProvider(HoconConfigurationSource source) : base(source)
{
+ _source = source ?? throw new ArgumentNullException(nameof(source));
}
///
@@ -31,7 +34,7 @@ public HoconConfigurationProvider(HoconConfigurationSource source) : base(source
/// The stream to read.
public override void Load(Stream stream)
{
- var parser = new HoconConfigurationFileParser();
+ var parser = new HoconConfigurationFileParser(_source.IncludeCallback);
try
{
Data = parser.Parse(stream);
diff --git a/src/Hocon.Extensions.Configuration/HoconConfigurationSource.cs b/src/Hocon.Extensions.Configuration/HoconConfigurationSource.cs
index c76a3fa..dbfa9cd 100644
--- a/src/Hocon.Extensions.Configuration/HoconConfigurationSource.cs
+++ b/src/Hocon.Extensions.Configuration/HoconConfigurationSource.cs
@@ -13,6 +13,16 @@ namespace Hocon.Extensions.Configuration
///
public class HoconConfigurationSource : FileConfigurationSource
{
+ ///
+ /// Default include callback.
+ ///
+ public static HoconIncludeCallbackAsync DefaultIncludeCallback { get; set; } = null;
+
+ ///
+ /// Include callback for this source.
+ ///
+ public HoconIncludeCallbackAsync IncludeCallback { get; set; } = null;
+
///
/// Builds the for this source.
///