Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protobuf-net and Blazor Trimming - good practices to follow? #321

Open
Dunge opened this issue Jan 26, 2024 · 2 comments
Open

protobuf-net and Blazor Trimming - good practices to follow? #321

Dunge opened this issue Jan 26, 2024 · 2 comments

Comments

@Dunge
Copy link

Dunge commented Jan 26, 2024

Sorry for this question, I'm aware it's more of a dotnet / Blazor domain than this lib specifically. But I know @mgravell is pretty knowledgeable about all of this so I assumed it wouldn't hurt to ask.

I'm wondering if there's a lot of "to-do" and "not-to-do" about using this lib and Blazor.

For example I have this very simple class:

    [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
    public class GenericData
    {
        public int Id { get; set; }

        private IEnumerable<Tuple<string, byte[]>> _data = new List<Tuple<string, byte[]>>();
        public IEnumerable<Tuple<string, byte[]>> Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }

This works perfectly using a normal console app, and it work using Blazor in Debug and Release, but as soon as it gets published using dotnet publish if I understand correctly trimming is automatically enabled for this project type and this exception comes up at runtime:

Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error reading next message. TargetInvocationException: Arg_TargetInvocationException InvalidOperationException: No serializer defined for type: System.Tuple`2[System.String,System.Byte[]]", DebugException="System.Reflection.TargetInvocationException: Arg_TargetInvocationException")
blazor.webassembly.js:1  ---> System.Reflection.TargetInvocationException: Arg_TargetInvocationException
blazor.webassembly.js:1  ---> System.InvalidOperationException: No serializer defined for type: System.Tuple`2[System.String,System.Byte[]]
blazor.webassembly.js:1    at ProtoBuf.Internal.ThrowHelper.NoSerializerDefined(Type type)
blazor.webassembly.js:1    at ProtoBuf.Internal.Serializers.TupleSerializer`1[[System.Collections.Generic.KeyValuePair`2[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Collections.Generic.List`1[[System.Tuple`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Byte[], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]..ctor(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, SerializerFeatures features, CompatibilityLevel compatibilityLevel)
blazor.webassembly.js:1    at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object , Object[] , Boolean )
blazor.webassembly.js:1    Exception_EndOfInnerExceptionStack
[...]

We are supposed to be able to disable this Trimming by setting this in the Blazor WASM project file: <PublishTrimmed>false</PublishTrimmed>.

Unfortunately for some reason, this doesn't work for me when targeting NET6. When I target NET8 it does fix the issues, but my project still need to target NET6 and even disabling trimming this way doesn't fix the error. This is my first question, and I actually asked it on StackOverflow in case anyone know what cause Trimming to still occurs on NET6 when I disable it.

But my "high level" question for protobuf-net is, what's to watch out for conceptually in order not to get these serializers types getting trimmed out? Is it just to avoid Tuple/KeyValuePair? It is everything about how this lib serialize stuff that is just incompatible with trimming and will never be?

What would be the "best" way to work around this issue, preferably letting Blazor still optimize its binaries with trimming? Can I use <TrimmerRootAssembly> to mark something to be ignored by the trimmer? Would that be the protobuf-net assembly themselves, or the assembly where my model is defined, or something else?

@Dunge
Copy link
Author

Dunge commented Jan 26, 2024

Updating my Blazor nuget from "6.0.11" to "6.0.26" seems to have fixed my issues preventing me to disable trimming.

My question still remain, any guidance on how to make protobuf-net serializers compatible with it?

@mgravell
Copy link
Member

mgravell commented Jan 27, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants