tylerjensen / ServiceWire

ServiceWire is a very fast and light weight service host and dynamic client library that simplifies the development and use of high performance remote procedure call (RPC) communication between .NET processes over Named Pipes or TCP/IP.
183 stars 40 forks source link

Error passing System.Uri between .NET 4.6.2 and .NET 8 #92

Open Leon99 opened 1 month ago

Leon99 commented 1 month ago

Just passing an instance of System.Uri between .NET 4.6.2 and .NET 8 processes gives this:

System.InvalidCastException: Object must implement IConvertible.
   at ServiceWire.Aspects.InterceptChannel.InvokeMethod(String metaData, Object[] parameters)

We found a possible reference to this issue in https://github.com/SubSonic-Core/SubSonic.Core.ServiceWire

implements additional typemapping so System.Uri can be mapped between framework and netcore runtimes

but that's an outdated fork, and it's unclear why that fix hasn't been merged here in 4 years. Any ideas much appreciated.

tylerje commented 1 month ago

Is there a reason you don't want to just use a string? Much faster. No type serialization difference. The other option is a custom serializer.

On Mon, Sep 9, 2024, 6:52 PM Leon V @.***> wrote:

Just passing an instance of System.Uri between .NET 4.6.2 and .NET 8 processes gives this:

System.InvalidCastException: Object must implement IConvertible. at ServiceWire.Aspects.InterceptChannel.InvokeMethod(String metaData, Object[] parameters)

We found a possible reference to this issue in https://github.com/SubSonic-Core/SubSonic.Core.ServiceWire

implements additional typemapping so System.Uri can be mapped between framework and netcore runtimes

but that's an outdated fork, and it's unclear why that fix hasn't been merged here in 4 years. Any ideas much appreciated.

— Reply to this email directly, view it on GitHub https://github.com/tylerjensen/ServiceWire/issues/92, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABCDWVOOH7Q6PX2QOCLFFOTZVY7FTAVCNFSM6AAAAABN5UJG66VHI2DSMVQWIX3LMV43ASLTON2WKOZSGUYTKMJXHE3DQMQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

Leon99 commented 1 month ago

Thanks for the quick response @tylerje!

System.Uri can provide platform-specific representations of a URI, which is required in our case. Also, it helps to have compile-time certainty about the nature of a string. The workaround is to do serialization "manually", but I'd rather delegate that to the transport level. Could you give me some ideas about the custom serializer option?

tylerje commented 1 month ago

https://github.com/tylerjensen/ServiceWire/blob/fad14780853d5b51aa4896b900cb20aa297b0bac/src/Tests/Unit/ServiceWireTests/NpTests.cs#L51

Have a look at this test.

https://github.com/tylerjensen/ServiceWire/blob/fad14780853d5b51aa4896b900cb20aa297b0bac/src/ServiceWire/Channel.cs#L16

And how the default serializer is used if one is not specified.

https://github.com/tylerjensen/ServiceWire/blob/fad14780853d5b51aa4896b900cb20aa297b0bac/src/ServiceWire/DefaultSerializer.cs#L7

Make a copy of the default. Alter as you like, including different handling for a Uri type. And that should give you what you need.

On Mon, Sep 9, 2024, 9:40 PM Leon V @.***> wrote:

Thanks for the quick response @tylerje https://github.com/tylerje!

System.Uri can provide platform-specific representations of a URI, which is required in our case. Also, it helps to have compile-time certainty about the nature of a string. The workaround is to do serialization "manually", but I'd rather delegate that to the transport level. Could you give me some ideas about the custom serializer option?

— Reply to this email directly, view it on GitHub https://github.com/tylerjensen/ServiceWire/issues/92#issuecomment-2339544815, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABCDWVJLGYLXOY5YZV4VHQDZVZS3NAVCNFSM6AAAAABN5UJG66VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMZZGU2DIOBRGU . You are receiving this because you were mentioned.Message ID: @.***>

tylerje commented 1 month ago

Of course, you will need to inject your custom serializer in the client and host constructors. Test your serializer between the two runtimes, and Bob's your uncle.

tylerje commented 1 month ago

The reason I don't burden the default serializer with multiple type resolvers between multiple runtimes is there are far too many combinations and that would bloat the default to cover rare edge cases.