找不到存储在共享 dotnet 项目中的原型文件

Can't find proto files stored in shared dotnet project

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

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

所以我使用 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>

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

例如:

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

由于您的 .proto 文件位于不同的目录中,因此您需要指定导入目录。您可以使用 <Protobuf ... /> 中的 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 添加路径变量来减少冗长。这也将使您免于拼写错误。

如果有帮助请告诉我,如果您需要什么请告诉我。