Fix placeholder proto namespace to use project's actual namespace

The WriteProtoFileTask now receives RootNamespace and AssemblyName from
MSBuild and uses them for the placeholder proto's csharp_namespace instead
of hardcoded "Generated.Grpc". This ensures GrpcGenerator can find the
service base types on first build, enabling gRPC service registration
to work without requiring a second build.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
David Nguyen 2026-01-22 02:19:50 -05:00
parent 377977b080
commit dfbef9d161
Signed by: david.nguyen
GPG Key ID: D5FB5A5715829326
2 changed files with 22 additions and 3 deletions

View File

@ -39,6 +39,16 @@ public class WriteProtoFileTask : Task
[Required] [Required]
public string ProtoFileName { get; set; } = string.Empty; public string ProtoFileName { get; set; } = string.Empty;
/// <summary>
/// The root namespace of the project (optional, falls back to AssemblyName)
/// </summary>
public string RootNamespace { get; set; } = string.Empty;
/// <summary>
/// The assembly name of the project (used for proto namespace if RootNamespace not set)
/// </summary>
public string AssemblyName { get; set; } = string.Empty;
public override bool Execute() public override bool Execute()
{ {
try try
@ -65,13 +75,20 @@ public class WriteProtoFileTask : Task
// Write a minimal placeholder proto file so Grpc.Tools doesn't fail // Write a minimal placeholder proto file so Grpc.Tools doesn't fail
// The real content will be generated on the next build // The real content will be generated on the next build
var placeholderProto = @"syntax = ""proto3""; // Use project's namespace so GrpcGenerator can find the service base types
var projectNamespace = !string.IsNullOrEmpty(RootNamespace) ? RootNamespace
: !string.IsNullOrEmpty(AssemblyName) ? AssemblyName
: "Generated";
var grpcNamespace = $"{projectNamespace}.Grpc";
option csharp_namespace = ""Generated.Grpc""; var placeholderProto = $@"syntax = ""proto3"";
option csharp_namespace = ""{grpcNamespace}"";
package cqrs; package cqrs;
// Placeholder proto file - will be regenerated on next build // Placeholder proto file - will be regenerated on next build
// Using namespace: {grpcNamespace}
"; ";
var placeholderOutputPath = Path.Combine(ProjectDirectory, OutputDirectory); var placeholderOutputPath = Path.Combine(ProjectDirectory, OutputDirectory);
Directory.CreateDirectory(placeholderOutputPath); Directory.CreateDirectory(placeholderOutputPath);

View File

@ -32,6 +32,8 @@
ProjectDirectory="$(MSBuildProjectDirectory)" ProjectDirectory="$(MSBuildProjectDirectory)"
IntermediateOutputPath="$(IntermediateOutputPath)" IntermediateOutputPath="$(IntermediateOutputPath)"
OutputDirectory="$(ProtoOutputDirectory)" OutputDirectory="$(ProtoOutputDirectory)"
ProtoFileName="$(GeneratedProtoFileName)" /> ProtoFileName="$(GeneratedProtoFileName)"
RootNamespace="$(RootNamespace)"
AssemblyName="$(AssemblyName)" />
</Target> </Target>
</Project> </Project>