I'm using YamlDotNet to parse simple configuration files (no deep nesting, etc.). The deserializer will parse strings containing duplicate fields, overwriting earlier values. For example,
foo: bar
foo: baz
is considered equivalent to
foo: baz
For my application, I would prefer that such duplicates cause an exception to be thrown. Is this possible?
The default node deserializers use the indexer to assign values. One way to achieve the desired behavior is to deserialize to a type that does not allow duplicate values, such as:
public class UniqueKeysDictionary<TKey, TValue>
: Dictionary<TKey, TValue>
, IDictionary<TKey, TValue>
{
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get { return base[key]; }
set { base.Add(key, value); }
}
}
A fully working example can be found here.
One significant issue with this solution is that it violates the contract of the indexer, whose behavior should be to overwrite the value.
Another approach would be to replace the implementation of GenericDictionaryNodeDeserializer
with one that uses the Add()
method instead of the indexer. This is the relevant portion of a different example that shows how to replace a node deserializer:
var deserializer = new Deserializer();
var objectDeserializer = deserializer.NodeDeserializers
.Select((d, i) => new {
Deserializer = d as ObjectNodeDeserializer,
Index = i
})
.First(d => d.Deserializer != null);
deserializer.NodeDeserializers[objectDeserializer.Index] =
new ValidatingNodeDeserializer(objectDeserializer.Deserializer);