tl;dr you'll need a simple workaround, because it's not supported out-of-the-box, see https://github.com/aaubry/YamlDotNet/issues/571
You need to have paremeter-less (0-arg) constructor in your record
for current (circa 13.x) YamlDotNet versions to be able to deserialize. That c-tor will be used solely to create the record in its pre-deserialization state, so you can provide it with normally invalid/unwanted values, like null
or other defaults. YamlDotNet will then use "magical" (reflection-based) setting methods anyway, and you can check for those invalid/unwanted values later to verify if the deserialized data actually has everything you need to have a complete record.
E.g.
public record Config(
string someParam,
string otherParam,
string yetAnotherParam
) {
public Config() : this(null, null, null) {
}
public void Validate() {
if (someParam == null || otherParam == null || yetAnotherParam == null) {
throw new ArgumentNullException("not all required fields were deserialized properly", (Exception) null);
}
}
}
will work just fine, and then you can just call Validate()
straight after deserialization if you want (yes, it's not as effective as library-level support for this, but still).
Alternatively (although I don't really advise to do it), you can e.g.:
- deserialize YAML to
object
using YamlDotNet,
- serialize that
object
to JSON via System.Text.Json
,
- and finally deserialize that JSON to your target record (via
System.Text.Json
as well)
It's both terrible for performance and would require even more obfuscation of the logic in code, but at least can be hidden in a helper method etc.