vs-streamjsonrpc
vs-streamjsonrpc copied to clipboard
InvalidCastException while generating proxies
Hey @AArnott, Thank you for your great efforts on this, really appreciate it!
I'm using vs-streamjsonrpc in my plugin framework scenario and looks like I found the bug.
When I try to use Attach<T> method it throws the following exception:
Unable to cast object of type '_proxy_PluginRpcContract.IGreeter_5143f248-4875-4810-b2d9-c9f6b0f4efeb' to type 'PluginRpcContract.IGreeter'.
at StreamJsonRpc.JsonRpc.Attach[T](JsonRpcProxyOptions options) in D:\src\Samples\vs-streamjsonrpc\src\StreamJsonRpc\JsonRpc.cs:line 730
at StreamJsonRpc.JsonRpc.Attach[T]() in D:\src\Samples\vs-streamjsonrpc\src\StreamJsonRpc\JsonRpc.cs:line 717
at PluginB.Plugin.ExecuteAsync() in C:\Users\V.Mykytiuk\source\repos\StreamJsonRpcTest\PluginB\Plugin.cs:line 20
at StreamJsonRpcTest.Program.<Main>d__0.MoveNext() in C:\Users\V.Mykytiuk\source\repos\StreamJsonRpcTest\StreamJsonRpcTest\Program.cs:line 32
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at StreamJsonRpcTest.Program.<Main>d__0.MoveNext() in C:\Users\V.Mykytiuk\source\repos\StreamJsonRpcTest\StreamJsonRpcTest\Program.cs:line 30
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at StreamJsonRpcTest.Program.<Main>d__0.MoveNext() in C:\Users\V.Mykytiuk\source\repos\StreamJsonRpcTest\StreamJsonRpcTest\Program.cs:line 30
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at StreamJsonRpcTest.Program.<Main>(String[] args)
It works fine for the first invocation, but all next invocations fail with that exception. I guess the problem is related to the multiple assemblies loaded in different Assembly Load Context. Each plugin (with its own dependencies) "lives" in a separate Assembly Load Context. The assembly where the contract (PluginRpcContract.IGreeter) for the proxy is defined also "lives" in the same ALC as the plugin itself, so there are multiple assemblies (PluginRpcContract) with the same name loaded in different ALCs.
I suppose the problem is related to ProxyGeneration.GetProxyModuleBuilder method, because when I commented out some code and return new ModuleBuilder for each interfaceType - it works and does not throw exception above.
Attaching the archive that reproduces the issue: StreamJsonRpcTest.zip
Could you please take a look? Maybe I am doing something wrong?
Thanks, Vasyl
Hi @AArnott! Hope you are doing well these days.
Just kindly asking whether you had a chance to look into the issue? Is there any possibility that this fix will be on your roadmap any time soon?
Regards :)
An interesting problem. I would certainly like JsonRpc proxies to work in the case of multiple ALCs. I don't think we have any tests to cover that scenario so I'm not too surprised if we have a bug in that area. I can't promise a timeline for fixing this at this point, but as I expect the fix won't take long, I'll optimistically schedule it for our 2.9 release.
@vmykytiuk it's a runtime bug. https://github.com/dotnet/runtime/issues/53271 https://github.com/dotnet/runtime/issues/43685 https://github.com/dotnet/runtime/issues/30917
@snikeguo, thanks for sharing. But it's not the same problem, since we don't use DispatchProxy
in StreamJsonRpc.