protobuf-net / protobuf-net.Grpc

GRPC bindings for protobuf-net and grpc-dotnet
Other
846 stars 106 forks source link

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

Open Dunge opened 5 months ago

Dunge commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

We have an AOT plan. We have more plans than time, however. We're working on it... ISH.

On Fri, 26 Jan 2024, 21:35 Dunge, @.***> wrote:

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?

— Reply to this email directly, view it on GitHub https://github.com/protobuf-net/protobuf-net.Grpc/issues/321#issuecomment-1912726570 or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMED6ZDLNKLVMCGJ4JTYQQOQVBFKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLLDTOVRGUZLDORPXI6LQMWWES43TOVSUG33NNVSW45FGORXXA2LDOOJIFJDUPFYGLKTSMVYG643JORXXE6NFOZQWY5LFVEYTSMRSGM2DQOJXQKSHI6LQMWSWS43TOVS2K5TBNR2WLKRSGEYDEOBYGIYDAMVHORZGSZ3HMVZKMY3SMVQXIZI . You are receiving this email because you are subscribed to this thread.

Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .