diff --git a/src/NetEscapades.Configuration.Yaml/YamlConfigurationExtensions.cs b/src/NetEscapades.Configuration.Yaml/YamlConfigurationExtensions.cs
index 97171eb..30fed83 100644
--- a/src/NetEscapades.Configuration.Yaml/YamlConfigurationExtensions.cs
+++ b/src/NetEscapades.Configuration.Yaml/YamlConfigurationExtensions.cs
@@ -7,6 +7,7 @@
using Microsoft.Extensions.FileProviders;
using NetEscapades.Configuration.Yaml;
using YamlDotNet.Core;
+using YamlDotNet.Serialization;
namespace Microsoft.Extensions.Configuration
{
@@ -19,39 +20,52 @@ public static class YamlConfigurationExtensions
/// Adds the YAML configuration provider at to .
///
/// The to add to.
- /// Path relative to the base path stored in
+ /// Path relative to the base path stored in
+ /// of .
+ /// The action that configures the YAML deserializer.
+ /// The .
+ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, Action configureDeserializer = null)
+ {
+ return AddYamlFile(builder, provider: null, path: path, optional: false, reloadOnChange: false, configureDeserializer: configureDeserializer);
+ }
+
+ ///
+ /// Adds the YAML configuration provider at to .
+ ///
+ /// The to add to.
+ /// Path relative to the base path stored in
/// of .
/// The .
public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path)
{
- return AddYamlFile(builder, provider: null, path: path, optional: false, reloadOnChange: false);
+ return AddYamlFile(builder, provider: null, path: path, optional: false, reloadOnChange: false, configureDeserializer: null);
}
///
/// Adds the YAML configuration provider at to .
///
/// The to add to.
- /// Path relative to the base path stored in
+ /// Path relative to the base path stored in
/// of .
/// Whether the file is optional.
/// The .
public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, bool optional)
{
- return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: false);
+ return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: false, configureDeserializer: null);
}
///
/// Adds the YAML configuration provider at to .
///
/// The to add to.
- /// Path relative to the base path stored in
+ /// Path relative to the base path stored in
/// of .
/// Whether the file is optional.
/// Whether the configuration should be reloaded if the file changes.
/// The .
- public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange)
+ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, string path, bool optional, bool reloadOnChange, Action configureDeserializer)
{
- return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: reloadOnChange);
+ return AddYamlFile(builder, provider: null, path: path, optional: optional, reloadOnChange: reloadOnChange, configureDeserializer: configureDeserializer);
}
///
@@ -59,12 +73,12 @@ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder build
///
/// The to add to.
/// The to use to access the file.
- /// Path relative to the base path stored in
+ /// Path relative to the base path stored in
/// of .
/// Whether the file is optional.
/// Whether the configuration should be reloaded if the file changes.
/// The .
- public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange)
+ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange, Action configureDeserializer)
{
if (builder == null)
{
@@ -74,17 +88,18 @@ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder build
{
throw new ArgumentException(Resources.FormatError_InvalidFilePath(), nameof(path));
}
-
+
return builder.AddYamlFile(s =>
{
s.FileProvider = provider;
s.Path = path;
s.Optional = optional;
s.ReloadOnChange = reloadOnChange;
+ s.ConfigureDeserializer = configureDeserializer;
s.ResolveFileProvider();
});
}
-
+
///
/// Adds a YAML configuration source to .
///
@@ -100,22 +115,22 @@ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder build
/// The to add to.
/// The to read the yaml configuration data from.
/// The .
- public static IConfigurationBuilder AddYamlStream(this IConfigurationBuilder builder, Stream stream)
+ public static IConfigurationBuilder AddYamlStream(this IConfigurationBuilder builder, Stream stream, Action configureDeserializer = null)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
- var data = ReadStream(stream);
+ var data = ReadStream(stream, configureDeserializer);
return builder.Add(s => s.Data = data);
- static IDictionary ReadStream(Stream s)
+ static IDictionary ReadStream(Stream s, Action configureDeserializer)
{
try
{
- return new YamlConfigurationStreamParser().Parse(s);
+ return new YamlConfigurationStreamParser(configureDeserializer).Parse(s);
}
catch (YamlException e)
{
@@ -124,4 +139,4 @@ static IDictionary ReadStream(Stream s)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NetEscapades.Configuration.Yaml/YamlConfigurationProvider.cs b/src/NetEscapades.Configuration.Yaml/YamlConfigurationProvider.cs
index 9de2bb4..10c6430 100644
--- a/src/NetEscapades.Configuration.Yaml/YamlConfigurationProvider.cs
+++ b/src/NetEscapades.Configuration.Yaml/YamlConfigurationProvider.cs
@@ -10,11 +10,16 @@ namespace NetEscapades.Configuration.Yaml
///
public class YamlConfigurationProvider : FileConfigurationProvider
{
- public YamlConfigurationProvider(YamlConfigurationSource source) : base(source) { }
+ private readonly YamlConfigurationSource _source;
+
+ public YamlConfigurationProvider(YamlConfigurationSource source) : base(source)
+ {
+ _source = source;
+ }
public override void Load(Stream stream)
{
- var parser = new YamlConfigurationStreamParser();
+ var parser = new YamlConfigurationStreamParser(_source.ConfigureDeserializer);
try
{
Data = parser.Parse(stream);
diff --git a/src/NetEscapades.Configuration.Yaml/YamlConfigurationSource.cs b/src/NetEscapades.Configuration.Yaml/YamlConfigurationSource.cs
index 2e80ca4..abde3b1 100644
--- a/src/NetEscapades.Configuration.Yaml/YamlConfigurationSource.cs
+++ b/src/NetEscapades.Configuration.Yaml/YamlConfigurationSource.cs
@@ -1,4 +1,6 @@
+using System;
using Microsoft.Extensions.Configuration;
+using YamlDotNet.Serialization;
namespace NetEscapades.Configuration.Yaml
{
@@ -7,10 +9,12 @@ namespace NetEscapades.Configuration.Yaml
///
public class YamlConfigurationSource : FileConfigurationSource
{
+ public Action ConfigureDeserializer { get; set; }
+
public override IConfigurationProvider Build(IConfigurationBuilder builder)
{
EnsureDefaults(builder);
return new YamlConfigurationProvider(this);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NetEscapades.Configuration.Yaml/YamlConfigurationStreamParser.cs b/src/NetEscapades.Configuration.Yaml/YamlConfigurationStreamParser.cs
index 38d262a..bd4cbf9 100644
--- a/src/NetEscapades.Configuration.Yaml/YamlConfigurationStreamParser.cs
+++ b/src/NetEscapades.Configuration.Yaml/YamlConfigurationStreamParser.cs
@@ -1,132 +1,133 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
-using System.Linq;
using Microsoft.Extensions.Configuration;
-using YamlDotNet.RepresentationModel;
+using YamlDotNet.Core;
+using YamlDotNet.Serialization;
namespace NetEscapades.Configuration.Yaml
{
internal class YamlConfigurationStreamParser
{
+ private readonly Action _configureDeserializer;
private readonly IDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase);
private readonly Stack _context = new Stack();
- private string _currentPath;
+
+ public YamlConfigurationStreamParser(Action configureDeserializer)
+ {
+ _configureDeserializer = configureDeserializer;
+ }
public IDictionary Parse(Stream input)
{
_data.Clear();
_context.Clear();
- // https://dotnetfiddle.net/rrR2Bb
- var yaml = new YamlStream();
- yaml.Load(new StreamReader(input, detectEncodingFromByteOrderMarks: true));
+ using var reader = new StreamReader(input, detectEncodingFromByteOrderMarks: true);
+ var parser = new Parser(reader);
+ var document = CreateDeserializer().Deserialize(parser);
- if (yaml.Documents.Any())
+ if (document is not IDictionary