Visitar URL original
`[CompositeResolverAttribute]` not yet that useful · Issue #1920 · MessagePack-CSharp/MessagePack-CSharp · GitHub
Skip to content

[CompositeResolverAttribute] not yet that useful #1920

Closed

Description

@AArnott

In my application that I'm migrating to v3, I have a bunch of data types that must be serialized:

  • Many are in the assembly with the messagepack reference
    • A few use [MessagePackObject]
    • Most use hand-authored formatters
  • Some are in an assembly w/o a messagepack reference. These have custom formatters declared in the above mentioned assembly.

I mix in the StandardResolver with my own resolver.

Ultimately, the resolver I use must be able to find the formatters that are declared in the same assembly as the data types as well as the formatters I define for data types outside my assembly. The former is easy and well automated. But I have to write my own resolver to find the formatters I define locally for data types found elsewhere because by default, StandardResolver only consults the automatically generated resolver for data types declared in the same assembly.

So I thought I'd create my own top-level resolver that forces the source generated resolver to always be asked, alongside the StandardResolver.

[CompositeResolver(typeof(GeneratedMessagePackResolver), typeof(StandardResolver))]
partial class CombinedResolver { }

The problem here is that CombinedResolver gets generated with this error:

#error No accessible default constructor or static Instance member on GeneratedMessagePackResolver.,

This is almost certainly because source generators (of which MessagePack v3 has two) cannot see each other's output, so it doesn't know that in fact GeneratedMessagePackResolver does in fact have an accessible instance:

public static readonly MsgPack::IFormatterResolver Instance = new GeneratedMessagePackResolver();

Activity

  1. added this to the v3.0 milestone on Aug 3, 2024
  2. AArnott commented on Aug 3, 2024

    @AArnott
    CollaboratorAuthor
    • Support formatters for CompositeResolverAttribute #1922 Also it seems like a missed opportunity that this CompositeResolverAttribute only supports taking resolvers where it could also take formatters.
      The CompositeResolver.Create function itself supported this. So if the attribute is meant to replace this for better perf, it ought to support both.
  3. AArnott commented on Aug 3, 2024

    @AArnott
    CollaboratorAuthor

    And given how tedious it is to figure out which formatters I can drop from my original list and which ones must stay because they are for data types in another assembly, I wish there were some way to automate this.

  4. AArnott commented on Aug 6, 2024

    @AArnott
    CollaboratorAuthor

    #error No accessible default constructor or static Instance member on GeneratedMessagePackResolver.,

    It looks like @AlanLiu90 may be addressing this in #1921. Thanks!

  5. AArnott commented on Aug 6, 2024

    @AArnott
    CollaboratorAuthor

    @AlanLiu90 would you be interested in taking on any of the other issues described here? 🙏🏻

  6. AlanLiu90 commented on Aug 6, 2024

    @AlanLiu90
    Contributor

    I think I can make a PR to support formatters for CompositeResolverAttribute.

    And given how tedious it is to figure out which formatters I can drop from my original list and which ones must stay because they are for data types in another assembly, I wish there were some way to automate this.

    I'm not sure if I understand it correctly. In my test, when I have a custom formatter for data type in other assembly, the source generated resolver contains this formatter automatically. It seems it's not necessary to write resolver for custom formatters manually.

  7. AArnott commented on Aug 8, 2024

    @AArnott
    CollaboratorAuthor

    Thank you for your help, @AlanLiu90.

    when I have a custom formatter for data type in other assembly, the source generated resolver contains this formatter automatically. It seems it's not necessary to write resolver for custom formatters manually.

    The issue isn't that the generated resolver doesn't include the formatter. The issue is that your resolver won't be consulted for it. The StandardResolver will only use your source generated resolver when searching for a data type in the same assembly. So your resolver has the answer, but nobody knows to ask for it.
    You can workaround this by including your source generated resolver yourself, alongside StandardResolver. And it was in doing this workaround that I discovered that [CompositeResolver] didn't support referencing the source-generated resolver (before your PR that fixes it).

  8. AlanLiu90 commented on Aug 9, 2024

    @AlanLiu90
    Contributor

    Thanks for your explanation. This issue was what I encountered before I made the PR.

  9. AArnott commented on Sep 25, 2024

    @AArnott
    CollaboratorAuthor

    Regarding the remaining problem, where formatters for data types in another assembly are picked up by the generated resolver but that resolver is not consulted, I believe an analyzer should be created that reports a new diagnostic until that formatter is referenced in a [CompositeResolver] attribute somewhere in that assembly.

    The only way to improve on that that I can imagine is if somehow the [CompositeResolver]-generated resolver didn't repeat the lookup code for these formatters that are already in the default generated resolver. But I'm not sure how to pull that off, and the improvement would probably be unnoticeable.

    But maybe the default-generated resolver should omit formatters in the assembly that are for types outside the assembly since they won't be used anyway.

  10. AArnott commented on Sep 25, 2024

    @AArnott
    CollaboratorAuthor

    Maybe the CompositeResolverAttribute can have an optional property that when set to true, will automatically include all formatters declared in the user assembly that are for external data types and the default-generated resolver. That way, there is no list for the user to maintain.

    I like that ... I think I'll build it this week.

  11. self-assigned this
    on Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions