andrewlock / StronglyTypedId

A Rosyln-powered generator for strongly-typed IDs
MIT License
1.5k stars 78 forks source link

Augment converter classes to allow extensions #96

Closed Greven145 closed 8 months ago

Greven145 commented 1 year ago

I have a case where I want to use my strongly typed id as a dictionary key when deserializing from JSON.

{
  "values": {
    "5edc8eb5-ca2d-48ed-96d5-93b3e690912d": "some value",
    "1dc766ac-dbbb-4775-bf22-8ac655227099": "some other value",
  }
}

I'm using System.Text.Json and I get an error The type 'MyId' is not a supported dictionary key using converter of type 'MyId+MyIdSystemTextJsonConverter'.

I can see two options, and maybe both would be useful

  1. Have the generated converter classes defined as partial classes. This would allow me to extend in code in my class with the additional overrides I might want

    [StronglyTypedId]
    public partial struct MyId {
    partial class MyIdSystemTextJsonConverter : JsonConverter<MyId>
    {
        /// <inheritdoc />
        public override MyId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
            var value = reader.GetString();
            return new MyId(Guid.Parse(value));
        }
    
        /// <inheritdoc />
        public override void WriteAsPropertyName(Utf8JsonWriter writer, MyId value, JsonSerializerOptions options) {
            writer.WriteStringValue(value.ToString());
        }
    }
    }
  2. Add (by default or by some additional config) the implementations of ReadAsPropertyName and WriteAsPropertyName

Currently I cannot add a second [System.Text.Json.Serialization.JsonConverter(typeof(MyMyIdConverter))] attribute, so I'm forced to use JSON serializer options whenever I want to deserialize.

If you agree this/these are something you'd like, I'd be happy to open a pull request

andrewlock commented 8 months ago

Sorry for the delay with this 😳. I agree on both points! I'm currently working on a big redesign of the library in this PR:

The main idea is to make the library much more maintainable while also giving people a mechanism to customise the generated IDs as much as they like. In that PR I've made both of these changes, but you'll be able to completely customise the generated IDs too 🙂