使用 Grpc.Tools 和 Protoc 插件生成额外的 C# 文件
Using Grpc.Tools with Protoc plug-in to generate additional C# files
我正在使用 Grpc.Tools (2.38.1) 从包含一些服务定义的 Test.proto
文件生成 C# 类型和 gRPC 存根。
为此,我在项目的 .csproj
文件中包含以下内容:
<ItemGroup>
<Protobuf Include="**/*.proto" />
</ItemGroup>
一切正常:我的 Test.proto
在项目的 obj/Debug 文件夹中被编译为 Test.cs
和 TestGrpc.cs
。它们中的类型可以从项目中的其他类型中引用。
但我也需要为该服务创建一个 WCF 接口,所以我想我可以使用自定义 Protoc 插件生成它。所以我写了一个简单的 Protoc 插件,写出一个包含接口的 TestWcf.cs
文件。然后,我将这个插件可执行文件放在名为 protoc-gen-blah.exe
的路径上,并将 .csproj
文件中的条目更新为:
<ItemGroup>
<Protobuf Include="**/*.proto" AdditionalProtocArguments="--blah_out=obj\Debug" />
</ItemGroup>
这正确地创建了 C# 文件,TestWcf.cs
,我的界面在:太棒了。
问题是我在 TestWcf.cs
中的接口不能从项目中的其他类型引用,除非我手动将生成的文件包含在项目中:我不必与其他生成的文件做的事情。
虽然 none 个文件默认包含在项目中——我必须启用 'Show All Files' 才能看到它们——Test.cs
和 TestGrpc.cs
旁边有箭头在 Solution Explorer 中,允许展开它们以显示其中的类型。 TestWcf.cs
没有这个箭头。所以 Visual Studio 以某种方式知道 Test.cs
和 TestGrpc.cs
是源代码文件。
有谁知道我需要做什么才能让 Visual Studio 像其他两个文件一样自动识别我生成的文件?
我怀疑它与 this part of the Grpc.Tools build target 有关,因为我注意到我的 TestWcf.cs
文件不包含在 Grpc.Tools clean 删除的文件中,但我可以'不明白为什么它不认为我生成的文件是 C#。
当我构建时,这是 Protoc 调用:
D:\...\Src\packages\Grpc.Tools.2.38.1\tools\windows_x86\protoc.exe --csharp_out=obj\Debug ⤶
--plugin=protoc-gen-grpc=D:\...\Src\packages\Grpc.Tools.2.38.1\tools\windows_x86\grpc_csharp_plugin.exe ⤶
--grpc_out=obj\Debug --proto_path=D:\...\Src\packages\Grpc.Tools.2.38.1\build\native\include ⤶
--proto_path=. --dependency_out=obj\Debug\xxxx_Test.protodep --error_format=msvs --blah_out=obj\Debug ⤶
Test.proto
依赖文件如下所示:
obj\Debug/Test.cs \
obj\Debug/TestGrpc.cs \
obj\Debug/TestWcf.cs: Test.proto
谢谢。
我认为问题是由 Grpc.Tools 中的 some logic 引起的,它通知 MSBuild 已生成的文件:
public override string[] GetPossibleOutputs(ITaskItem protoItem)
{
...
var outputs = new string[doGrpc ? 2 : 1];
...
outputs[0] = Path.Combine(outdir, filename) + ".cs";
if (doGrpc)
{
...
outputs[1] = Path.Combine(grpcdir, filename) + "Grpc.cs";
}
return outputs;
}
此代码仅适用于从 Protocol Buffer 源 (name.proto
) 生成的两个文件:Protocol Buffers 代码生成 (name.cs
) 和 gRPC 代码生成 (nameGrpc.cs
).它没有获取附加文件并通知 MSBuild 它存在,因此 Visual Studio 不认为它是代码。
除了更改 Grpc.Tools 代码之外别无他法。
我正在使用 Grpc.Tools (2.38.1) 从包含一些服务定义的 Test.proto
文件生成 C# 类型和 gRPC 存根。
为此,我在项目的 .csproj
文件中包含以下内容:
<ItemGroup>
<Protobuf Include="**/*.proto" />
</ItemGroup>
一切正常:我的 Test.proto
在项目的 obj/Debug 文件夹中被编译为 Test.cs
和 TestGrpc.cs
。它们中的类型可以从项目中的其他类型中引用。
但我也需要为该服务创建一个 WCF 接口,所以我想我可以使用自定义 Protoc 插件生成它。所以我写了一个简单的 Protoc 插件,写出一个包含接口的 TestWcf.cs
文件。然后,我将这个插件可执行文件放在名为 protoc-gen-blah.exe
的路径上,并将 .csproj
文件中的条目更新为:
<ItemGroup>
<Protobuf Include="**/*.proto" AdditionalProtocArguments="--blah_out=obj\Debug" />
</ItemGroup>
这正确地创建了 C# 文件,TestWcf.cs
,我的界面在:太棒了。
问题是我在 TestWcf.cs
中的接口不能从项目中的其他类型引用,除非我手动将生成的文件包含在项目中:我不必与其他生成的文件做的事情。
虽然 none 个文件默认包含在项目中——我必须启用 'Show All Files' 才能看到它们——Test.cs
和 TestGrpc.cs
旁边有箭头在 Solution Explorer 中,允许展开它们以显示其中的类型。 TestWcf.cs
没有这个箭头。所以 Visual Studio 以某种方式知道 Test.cs
和 TestGrpc.cs
是源代码文件。
有谁知道我需要做什么才能让 Visual Studio 像其他两个文件一样自动识别我生成的文件?
我怀疑它与 this part of the Grpc.Tools build target 有关,因为我注意到我的 TestWcf.cs
文件不包含在 Grpc.Tools clean 删除的文件中,但我可以'不明白为什么它不认为我生成的文件是 C#。
当我构建时,这是 Protoc 调用:
D:\...\Src\packages\Grpc.Tools.2.38.1\tools\windows_x86\protoc.exe --csharp_out=obj\Debug ⤶
--plugin=protoc-gen-grpc=D:\...\Src\packages\Grpc.Tools.2.38.1\tools\windows_x86\grpc_csharp_plugin.exe ⤶
--grpc_out=obj\Debug --proto_path=D:\...\Src\packages\Grpc.Tools.2.38.1\build\native\include ⤶
--proto_path=. --dependency_out=obj\Debug\xxxx_Test.protodep --error_format=msvs --blah_out=obj\Debug ⤶
Test.proto
依赖文件如下所示:
obj\Debug/Test.cs \
obj\Debug/TestGrpc.cs \
obj\Debug/TestWcf.cs: Test.proto
谢谢。
我认为问题是由 Grpc.Tools 中的 some logic 引起的,它通知 MSBuild 已生成的文件:
public override string[] GetPossibleOutputs(ITaskItem protoItem)
{
...
var outputs = new string[doGrpc ? 2 : 1];
...
outputs[0] = Path.Combine(outdir, filename) + ".cs";
if (doGrpc)
{
...
outputs[1] = Path.Combine(grpcdir, filename) + "Grpc.cs";
}
return outputs;
}
此代码仅适用于从 Protocol Buffer 源 (name.proto
) 生成的两个文件:Protocol Buffers 代码生成 (name.cs
) 和 gRPC 代码生成 (nameGrpc.cs
).它没有获取附加文件并通知 MSBuild 它存在,因此 Visual Studio 不认为它是代码。
除了更改 Grpc.Tools 代码之外别无他法。