【问题标题】:Can't find proto files stored in shared dotnet project找不到存储在共享 dotnet 项目中的 proto 文件
【发布时间】:2022-06-11 15:44:11
【问题描述】:

我有一个核心项目,里面有一堆原型文件。核心项目没有安装任何 GRPC 代码生成包

我正在尝试在将编译和使用它们的服务中引用这些 proto 文件。

所以我使用dotnet-grpc 将这些文件添加到此项目中,从而将以下itemgroup 添加到csproj

 <ItemGroup>
    <Protobuf Include="..\BonnieAndClydesdale.Core\Protos\Enums\HorseGender.proto" Link="Protos\Enums\HorseGender.proto"/>
    <Protobuf Include="..\BonnieAndClydesdale.Core\Protos\Models\AdDetails.proto" Link="Protos\Models\AdDetails.proto"/>
    <Protobuf Include="..\BonnieAndClydesdale.Core\Protos\Models\HorseDetails.proto" Link="Protos\Models\HorseDetails.proto"/>
    <Protobuf Include="..\BonnieAndClydesdale.Core\Protos\Services\AdService.proto" Link="Protos\Services\AdService.proto"/>
  </ItemGroup>

但是,现在我遇到了错误,即我的 proto 文件找不到它们的各种导入。

例如:

syntax = "proto3";
import "HorseDetails.proto";


option csharp_namespace = "BonnieAndClydesdale.Core.Models";
package Ads;

message AdDetails {
  string title = 1;
  double asking_price = 2; //TODO - Custom Decimal
  string short_description = 3;
  string image_url = 4;
  string location = 5;
  HorseDetails horse_details = 6;
}

找不到HorseDetails.proto

我对这里发生的事情有点困惑,因为我没有更改任何文件布局,如果文件直接放在我的服务项目中,这很好。

有什么想法吗?


更多详情:

这里是原型文件:

HorseGender.proto

syntax = "proto3";

option csharp_namespace = "BonnieAndClydesdale.Core.Enums";
package Ads;

enum HorseGender{
  Stallion = 0;
  Gelding = 1;
  Mare = 2;
}

AdDetails.proto

syntax = "proto3";
import "HorseDetails.proto";


option csharp_namespace = "BonnieAndClydesdale.Core.Models";
package Ads;

message AdDetails {
  string title = 1;
  double asking_price = 2; //TODO - Custom Decimal
  string short_description = 3;
  string image_url = 4;
  string location = 5;
  HorseDetails horse_details = 6;
}

HorseDetails.proto

syntax = "proto3";
import "HorseGender.proto";

option csharp_namespace = "BonnieAndClydesdale.Core.Models";
package Ads;

message HorseDetails
{
  string name = 1;
  int32 age_in_years = 2;
  HorseGender gender = 3;
  string breed = 4;
  float height = 5; // TODO - custom decimal
}

AdService.proto

syntax = "proto3";
import "AdDetails.proto";

option csharp_namespace = "BonnieAndClydesdale.Core";

package Ads;

service AdService {
  rpc GetAds (AdRequest) returns (AdReply);
}

message AdRequest {
}

message AdReply {
  repeated AdDetails AdDetails = 1;
}

还有文件树:

.
├── BonnieAndClydesdale.AdService
│  ├── BonnieAndClydesdale.AdService.csproj
│  ├── Dockerfile
│  ├── appsettings.Development.json
│  ├── appsettings.json
│  ├── Program.cs
│  ├── Properties
│  │  └── launchSettings.json
│  ├── Repositories
│  │  ├── AdsRepositoryStub.cs
│  │  └── IAdsRepository.cs
│  └── Services
│     └── AdService.cs
├── BonnieAndClydesdale.Core
│  ├── BonnieAndClydesdale.Core.csproj
│  ├── Clients
│  │  ├── AdServiceClientStub.cs
│  │  └── IAdServiceClient.cs
│  ├── Enums
│  │  └── HorseGender.cs
│  ├── Models
│  │  ├── AdDetails.cs
│  │  └── HorseDetails.cs
│  └── Protos
│     ├── Enums
│     │  └── HorseGender.proto
│     ├── Models
│     │  ├── AdDetails.proto
│     │  └── HorseDetails.proto
│     └── Services
│        └── AdService.proto
├── BonnieAndClydesdale.MainSite
│  ├── _Imports.razor
│  ├── App.razor
│  ├── BonnieAndClydesdale.MainSite.csproj
│  ├── Pages
│  │  ├── ForSale.cs
│  │  ├── ForSale.razor
│  │  └── Index.razor
│  ├── Program.cs
│  ├── Properties
│  │  └── launchSettings.json
│  ├── Shared
│  │  ├── Components
│  │  │  ├── AdCard.cs
│  │  │  └── AdCard.razor
│  │  └── Layouts
│  │     ├── MainLayout.cs
│  │     ├── MainLayout.razor
│  │     └── NavMenu.razor
│  └── wwwroot
│     ├── favicon.ico
│     ├── index.html
│     └── sample-data
│        └── weather.json
└── BonnieAndClydesdale.sln

【问题讨论】:

  • 你能给我们其他文件的定义和目录树吗?我会尝试复制它并帮助你。
  • 谢谢,@ClémentJean - 我已经添加了你想要的信息

标签: c# asp.net-core protocol-buffers grpc


【解决方案1】:

由于您的 .proto 文件位于不同的目录中,您需要指定导入目录。您可以使用 &lt;Protobuf ... /&gt; 中的 AdditionalImportDirs 来做到这一点。

所以 ItemGroup 变成了这样:

<ItemGroup>
    <Protobuf
        Include="..\BonnieAndClydesdale.Core\Protos\Enums\HorseGender.proto"
        Link="Protos\Enums\HorseGender.proto" />
    <Protobuf
        AdditionalImportDirs="..\BonnieAndClydesdale.Core\Protos"
        Include="..\BonnieAndClydesdale.Core\Protos\Models\AdDetails.proto"
        Link="Protos\Models\AdDetails.proto" />
    <Protobuf
        AdditionalImportDirs="..\BonnieAndClydesdale.Core\Protos"
        Include="..\BonnieAndClydesdale.Core\Protos\Models\HorseDetails.proto"
        Link="Protos\Models\HorseDetails.proto" />
    <Protobuf
        AdditionalImportDirs="..\BonnieAndClydesdale.Core\Protos"
        Include="..\BonnieAndClydesdale.Core\Protos\Services\AdService.proto"
        Link="Protos\Models\HorseDetails.proto" />
</ItemGroup>

我决定将导入目录指定为所有原型的根目录。所以现在,你需要像这样导入:

AdDetails.proto

...
import "Models/HorseDetails.proto";
...

HorseDetails.proto

...
import "Enums/HorseGender.proto";
...

AdService.proto

...
import "Models/AdDetails.proto";
...

这是我做出的设计选择。您完全可以使用AdditionalImportDirs 更具体,因此仅指定文件名,但在我看来添加根目录更清楚一些。

之后,您显然可以通过在PropertyGroup 中向..\BonnieAndClydesdale.Core\Protos 添加路径变量来减少冗长。这也将避免您出现拼写错误。

【讨论】:

  • 嗨,这似乎解决了我的问题:谢谢!你能告诉我AdditionalImportDirs到底是做什么的吗?它是从您链接的文件中查找引用的原始文件的地方吗?
  • @Persistence 是的,这告诉 protoc 在哪里可以找到您在 .proto 文件中导入的发现。
猜你喜欢
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多