diff --git a/src/Hocon.Configuration/Config.cs b/src/Hocon.Configuration/Config.cs
index 6e32b800..b2c0b91d 100644
--- a/src/Hocon.Configuration/Config.cs
+++ b/src/Hocon.Configuration/Config.cs
@@ -18,22 +18,32 @@ namespace Hocon
///
public class Config : HoconRoot
{
+ [Obsolete("For json serialization/deserialization only", true)]
+ private Config()
+ {
+ }
+
///
///
/// Initializes a new instance of the class.
///
- private Config()
+ private Config(HoconValue value, Config fallback)
{
+ Fallback = fallback;
+ Value = value;
+
+ Root = GetRootValue();
}
- ///
+ ///
/// The root node to base this configuration.
/// "The root value cannot be null."
public Config(HoconRoot root) : base(root?.Value, root?.Substitutions ?? Enumerable.Empty())
{
+ Root = GetRootValue();
}
- ///
+ ///
/// The configuration to use as the primary source.
/// The configuration to use as a secondary source.
/// The source configuration cannot be null.
@@ -41,6 +51,8 @@ public Config(HoconRoot source, Config fallback) : base(source?.Value,
source?.Substitutions ?? Enumerable.Empty())
{
Fallback = fallback;
+
+ Root = GetRootValue();
}
///
@@ -54,27 +66,12 @@ public Config(HoconRoot source, Config fallback) : base(source?.Value,
///
/// The configuration used as a secondary source.
///
- public Config Fallback { get; private set; }
+ public Config Fallback { get; }
///
/// The root node of this configuration section
///
- public virtual HoconValue Root
- {
- get
- {
- var elements = new List();
- for (var config = this; config != null; config = config.Fallback?.Copy())
- {
- elements.AddRange(config.Value);
- }
-
- var aggregated = new HoconValue(null);
- aggregated.AddRange(elements.AsEnumerable().Reverse());
-
- return aggregated;
- }
- }
+ public virtual HoconValue Root { get; }
///
/// Returns string representation of , allowing to include fallback values
@@ -95,11 +92,7 @@ public string ToString(bool useFallbackValues)
protected Config Copy()
{
//deep clone
- return new Config
- {
- Fallback = Fallback?.Copy(),
- Value = (HoconValue) Value.Clone(null)
- };
+ return new Config((HoconValue) Value.Clone(null), Fallback?.Copy());
}
protected override HoconValue GetNode(HoconPath path, bool throwIfNotFound = false)
@@ -144,14 +137,10 @@ public virtual Config WithFallback(Config fallback)
{
if (fallback == this)
throw new ArgumentException("Config can not have itself as fallback", nameof(fallback));
-
- var clone = Copy();
-
- var current = clone;
- while (current.Fallback != null) current = current.Fallback;
- current.Fallback = fallback.Copy();
-
- return clone;
+
+ // If Fallback is not set - we will set it in new copy
+ // If Fallback was set - just use it, but with adding new fallback values
+ return new Config((HoconValue) Value.Clone(null), Fallback?.WithFallback(fallback) ?? fallback);
}
///
@@ -199,6 +188,24 @@ public override IEnumerable> AsEnumerable()
used.Add(kvp.Key);
}
}
+
+ ///
+ /// Performs aggregation of Value and all Fallbacks into single object
+ ///
+ private HoconValue GetRootValue()
+ {
+ var elements = new List();
+
+ for (var config = this; config != null; config = config.Fallback?.Copy())
+ {
+ elements.AddRange(config.Value);
+ }
+
+ var aggregated = new HoconValue(null);
+ aggregated.AddRange(elements.AsEnumerable().Reverse());
+
+ return aggregated;
+ }
}
///