Closed DSanchen closed 3 years ago
It should work with any Google.Protobuf version >= 3.14. Can you try the latest GrpcDotNetNamedPipes version I published (1.4.0)? There's a bug fix that might be relevant.
Hi cyanfish, I tried it with your NuGet Package V1.40 but still have no success. I've added a callback to AppDomain.CurrentDomain.AssemblyResolve. When the client tries to connect to the server, the assemblyResolve callback is called, specifying "Google.Protobuf, Version=3.14.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604" as the assembly to resolve...
When I compile your source code as package reference, there is still the fixed dependency to Google.Protobuf 3.14.0 in the csproj-file. Then, when the client tries to call the first service-call I can see an exception happening in PipeReader.ReadLoop() that is caught:
This seems like Package Hell to me, that cannot fix when using NuGet Packages....
When I self-compile your code with
I can't reproduce the issue. As you can see on the nuget package, the dependencies are defined correctly.
Sounds like an issue with your Nuget configuration but I don't know exactly. Adding a binding redirect may work.
Hi cyanfish,
Thanks for your answer and your time. You're right, it has something to do with binding redirection, I just don't know how to fix it (properly).
The point is, that I'm loading the assembly which starts the GRPC server dynamically at runtime (using Castle Windsor). The started application itself does not know (and should not know) anything about gRPC or Protobuf.
Then, when the server is started, everything seems fine, until the client connects to the server. At this point, your PipeReader class gets created, and the ReadLoop starts. At the point, where the ReadLoop calls NamedPipeTransport.Read(), the TransportMessage Type is constructed for the first time. This is the moment, when the application domain think it has to load Google.Protobuf Version 3.14.0.0 which it can't because 3.15.7 is loaded...
Of course I can include the
One way to solve it (quite nicely), is to provide the already loaded protobuf-assembly on the AssemblyResolve Event:
private static Assembly AssemblyResolve_With_LoadedAssembly(object sender, ResolveEventArgs args)
{
Func<AssemblyName, AssemblyName, bool> isReplacementFor = (aName, bName) => aName.Name.Equals(bName.Name) && aName.GetPublicKeyToken().SequenceEqual(bName.GetPublicKeyToken());
try
{
Assembly replacementAssembly = AppDomain.CurrentDomain.GetAssemblies().Where(assy => isReplacementFor(assy.GetName(), new AssemblyName(args.Name))).Single();
return replacementAssembly;
}
catch
{
return null;
}
}
Just came across your package for Named Pipes for gRPC, which is exactly what I was looking for (I'm looking for alternatives for WCF with namedpipebindings...) Unfortunately using the package as is did not work for me "out of the box", I somewhere got an "the Pipe is broken" exception. Digging further in, I realized that the pipe worked fine, rather it was the fact that you "need" Google.Protobuf 3.14, but I use another Package (Akka.Streams) that itself needs Google.Protobuf >= 3.15.6
Would it be possible, to specify a dependency of Google.Protobuf 3.* ? I tried compiling it like that and it worked for me...