Fix GrpcGenerator type mapping for commands and nullable primitives

- Add proper complex type mapping for command results (same as queries already had)
- Handle nullable primitives (long?, int?, etc.) with default value fallback
- Fixes CS0029 and CS0266 compilation errors in generated gRPC service implementations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
David Nguyen 2026-01-06 11:29:32 -05:00
parent 99aebcf314
commit 661f5b4b1c
Signed by: david.nguyen
GPG Key ID: D5FB5A5715829326
2 changed files with 41 additions and 6 deletions

View File

@ -904,9 +904,14 @@ namespace Svrnty.CQRS.Grpc.Generators
}
// Default: direct assignment (strings, ints, bools, etc.)
if (prop.IsNullable && prop.Type.Contains("string"))
if (prop.IsNullable)
{
return $"{indent}{prop.Name} = {source} ?? string.Empty,";
if (prop.Type.Contains("string"))
{
return $"{indent}{prop.Name} = {source} ?? string.Empty,";
}
// Handle nullable primitives (long?, int?, etc.) - use default value
return $"{indent}{prop.Name} = {source} ?? default,";
}
return $"{indent}{prop.Name} = {source},";
}
@ -1921,14 +1926,38 @@ namespace Svrnty.CQRS.Grpc.Generators
if (command.HasResult)
{
sb.AppendLine(" var result = await handler.HandleAsync(command, context.CancellationToken);");
// Handle Guid result conversion
if (command.ResultFullyQualifiedName?.Contains("System.Guid") == true)
// Generate response with mapping if complex type
if (command.IsResultPrimitiveType)
{
sb.AppendLine($" return new {responseType} {{ Result = result.ToString() }};");
// Handle primitive type result conversion (e.g., Guid.ToString())
if (command.ResultFullyQualifiedName?.Contains("System.Guid") == true)
{
sb.AppendLine($" return new {responseType} {{ Result = result.ToString() }};");
}
else
{
sb.AppendLine($" return new {responseType} {{ Result = result }};");
}
}
else
{
sb.AppendLine($" return new {responseType} {{ Result = result }};");
// Complex type - need to map from C# type to proto type
sb.AppendLine($" if (result == null)");
sb.AppendLine($" {{");
sb.AppendLine($" return new {responseType}();");
sb.AppendLine($" }}");
sb.AppendLine($" return new {responseType}");
sb.AppendLine(" {");
sb.AppendLine($" Result = new {command.ResultType}");
sb.AppendLine(" {");
foreach (var prop in command.ResultProperties)
{
var assignment = GenerateResultPropertyMapping(prop, "result", " ");
sb.AppendLine(assignment);
}
sb.AppendLine(" }");
sb.AppendLine(" };");
}
}
else

View File

@ -108,6 +108,12 @@ internal static class ProtoFileTypeMapper
needsImport = true;
importPath = "google/protobuf/timestamp.proto";
return "google.protobuf.Timestamp";
case "DateOnly":
// DateOnly serialized as string (YYYY-MM-DD format)
return "string";
case "TimeOnly":
// TimeOnly serialized as string (HH:mm:ss format)
return "string";
case "TimeSpan":
needsImport = true;
importPath = "google/protobuf/duration.proto";