Windows version: Windows 10, 1903
Does the bug reproduce also in WPF for .NET Framework 4.8?: No
Problem description:
Trying to use a gRPC service as shown in the AspNetDocs-repo in a WPF app, <UseWPF>true</UseWPF>, results in a build error. Visual Studio and VSCode does not report the problem in intellisense but it appears when doing a dotnet build .sln.
Actual behavior:
Results in a
error CS0246: The type or namespace name 'Greet' could not be found (are you missing a using directive or an assembly reference?)
When building. Greet here is the gRPC service defined in a .proto file.
Expected behavior:
Build & run with no error.
Minimal repro:
I made a repro-repo here.
Not sure if this is the correct repository to open the issue in, but I can't reproduce the error when using a console app.
It鈥檚 a good idea to open an issue against AspNet as well.
@hayer @vatsan-madhavan
This looks like an issue with the interaction between gRPC targets and PBT:
MainWindow.xaml.cs(1,7): error CS0246: The type or namespace name 'Greet' could not be found (are you missing a using directive or an assembly reference?) [d:\repos\grpcfail\DemoWpfApp\DemoWpfApp_t1mpsdxb_wpftmp.csproj]
It looks like the temp project used for markup compilation doesn't have access to the generated gRPC class from the protobuffer file. From looking at the buildlog, the temp project is building before the gRPC targets have run.
I believe you can split the client gRPC portion into a separate project and it will build fine. I did this here and it all built fine. I didn't test anything out at runtime, so you might want to ensure it works.
WPF itself doesn't seem to have anything it can do to fix this. I think this is a bug for the gRPC team to ensure their targets are aware of the temp projects used for markup compilation. Of course the above is a simple workaround that should allow you to utilize the types.
Let me know if this works for you.
@rladuca yes, its seems like you can split it into a library project. But isn't it supposed to work directly with .NET Core 3 WPF projects?
@hayer You're probably correct, and maybe this is actually something WPF is doing incorrectly. This could be related to us not getting NuGet PackageReferences in our temporary markup projects.
@ryalanms Do you think this is related to https://github.com/NuGet/Home/issues/5894? It seems like if we ensured that PackageReferences flowed to the temp project, it should get and use all the appropriate targets from gRPC (and other generators) without an issue.
What seems to be happening is that the WPF MSBuild target is generating a temporary project, like DemoWpfApp_rdowyz5w_wpftmp.csproj, this project does not include the code files generated by protobuf.
There is also a
DefaultItemExcludes = ;bin\Debug\/**;obj\Debug\/**;bin\/**;obj\/**;**/*.user;**/*.*proj;**/*.sln;**/*.vssscc
which is passed throughout the build which would include the generated code files.
Guessing the correct solution is to have generated code files passed explicitly into _some_ WPF build target. Still looking into that.
@hayer Without PackageReferences making it to the temp project, it will never pull in the build targets for gRPC. If we had that working, then gRPC would generate the code files in the temp project's build.
WPF temp projects used for markup compilation are basically ignorant of NuGet, seems to be the cause of this and the issue I linked (which is also about missing targets from a PackageReference).
@vatsan-madhavan and @ryalanms have, I believe, done some thinking about this in the past.
@rladuca yes, that's how far I got in my investigation. Was hoping this was something else as the issues linked to earlier seems to have 'stopped'. Guessing this can be closed now?
@grubioe I'm working on a gRPC e-book for Microsoft Docs and I've run into this issue. Since you've moved it to the 5.0 milestone, should I document the workaround of using a separate client library in my book for 3.0?
Yes please, you can document the workaround for 3.0. Thanks!
@markrendle @grubioe link to the workaround
FYI I'm experiencing this same issue on .NET Framework 4.7.2 as well. WPF projects create a temporary project that does not include the Protobuf targets in the build.
The problem seems to be that Grpc.Tools hooks into BeforeCompile, which appears to not be executed for the temporary project.
Hooking it into CoreCompile instead (eg. by defining <CoreCompileDependsOn>$(CoreCompileDependsOn);Protobuf_Compile</CoreCompileDependsOn> in an imported targets file) successfully works around the problem.
A potential nasty solution is to copy the nuget.g.*.props and targets.
That should end up important the right props and targets from packages.
See comment here: https://github.com/NuGet/Home/issues/5894#issuecomment-585917595.
If indeed this is the issue that will track NuGet/Home#5894 going forward, please update the title of this issue to match the other one or somehow similarly reflect the general problem instead of its current title which suggests a far more limited scope.
Possible solutions:
Just a note that this is not limited to gRPC only. I have a PackageReference that has some source codes (*.cs files) that I want to include in my project. The files are not picked up (although are shown correctly in the IDE) at compile time.
Yes, same with two NuGet packages that I contribute to which conditionally include source files through .targets.
We've also run into this: https://github.com/dotnet/wpf/issues/3308. It looks like .NET/Roslyn itself has a specific workaround to avoid this:
https://github.com/dotnet/arcade/blob/cbfa29d4e859622ada3d226f90f103f659665d31/src/Microsoft.DotNet.Arcade.Sdk/tools/Workarounds.props#L14.
https://github.com/dotnet/arcade/pull/2003/files#diff-da13dd1a6eaacec825fa32a6a7f776bfR7
Most helpful comment
Just a note that this is not limited to gRPC only. I have a PackageReference that has some source codes (*.cs files) that I want to include in my project. The files are not picked up (although are shown correctly in the IDE) at compile time.