-
Notifications
You must be signed in to change notification settings - Fork 48
Description
This is useful for being able to "extend" an existing JsonFSharpConverter in a way that is "just like the existing one, but altered".
It can be used from within other JsonConverters, when they decide that parts of the format should be altered.
Use case:
I have a type
type Envelope<'a> =
{ id : int
headers : Map<string, string>
data : 'a }in which 'a can be an F# type, often a union type.
I am writing a JsonConverter (the factory) to be able to format the value according to some standard, like:
{
"id": 1,
"headers":
{
"fizz": "buzz",
"foo": "bar"
},
"messageType": "Events.Order.Cancelled",
"data":
{
"id": 123,
"reason": "just"
}
}Note that in this case messageType sits outside of the data, so data has to be formatted as JsonUnionEncoding.ExternalTag ||| JsonUnionEncoding.NamedFields, regardless of how the formatter is configured otherwise.
So I want to override this for the 'a within that envelope.
The logical case here seems to be to add an override for the type within the factory.
But I wanted to preserve other overrides that might be configured, since that 'a can internally contain any of these.
I tried to add an override for typedefof<Envelope<_>> at the top level, but it obviously didn't work since It means providing options for the Envelope itself and not for the 'a inside it.
If JsonFSharpConverter provided the way of extracting options and overrides then it would be possible to do something like (pseudocode):
override this.CreateConverter(typeToConvert, options) =
let fsConverter = options.Converters |> findFsharpConverter // returns existing one or default
let newConverter = JsonFSharpOptions(fsConverter.options, fsConverter.overrides |> updatedOverridesForMyType)
let safeOptions = JsonSerializerOptions(options)
safeOptions.Converters |> replaceFsharpConverter newConverter
// now use safeOptions instead of optionsIdeally it'd be great to be able to declare an override for generic parameters, like "for the parameter within this generic use this override", but I don't even know how to express that :)))