Skip to content

Commit 4ed34e4

Browse files
committed
tweaks to reflection services code:
- rename ServicesExtensions due to collision; combine two static classes - update Reflection.cs with latest bits - use the TypeModel that is configured on the binder, not necessarily the default - fixup intellisense - yak some IDE warnings
1 parent edf6d80 commit 4ed34e4

File tree

8 files changed

+86
-79
lines changed

8 files changed

+86
-79
lines changed

src/protobuf-net.Grpc.AspNetCore.Reflection/EndpointRouteBuilderExtensions.cs

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/protobuf-net.Grpc.AspNetCore.Reflection/ServicesExtensions.cs renamed to src/protobuf-net.Grpc.AspNetCore.Reflection/ReflectionExtensions.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
using Grpc.AspNetCore.Server;
2-
using Grpc.AspNetCore.Server.Model;
3-
using Grpc.Core;
2+
using Microsoft.AspNetCore.Builder;
43
using Microsoft.AspNetCore.Routing;
54
using Microsoft.Extensions.DependencyInjection;
65
using Microsoft.Extensions.DependencyInjection.Extensions;
7-
using Microsoft.Extensions.Logging;
86
using ProtoBuf.Grpc.Configuration;
97
using ProtoBuf.Grpc.Reflection;
108
using System;
11-
using System.Collections.Generic;
129
using System.Linq;
1310

1411
namespace ProtoBuf.Grpc.Server
1512
{
1613
/// <summary>
17-
/// Provides extension methods to the IServiceCollection API
14+
/// Provides extension methods to provide protobuf-net.Grpc reflection services
1815
/// </summary>
19-
public static class ServicesExtensions
16+
public static class ReflectionExtensions
2017
{
18+
/// <summary>
19+
/// Maps incoming requests to the gRPC reflection service.
20+
/// This service can be queried to discover the gRPC services on the server.
21+
/// </summary>
22+
/// <param name="builder">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
23+
/// <returns>An <see cref="IEndpointConventionBuilder"/> for endpoints associated with the service.</returns>
24+
public static IEndpointConventionBuilder MapCodeFirstGrpcReflectionService(this IEndpointRouteBuilder builder)
25+
{
26+
if (builder is null)
27+
{
28+
throw new ArgumentNullException(nameof(builder));
29+
}
30+
31+
return builder.MapGrpcService<ReflectionService>();
32+
}
33+
2134
/// <summary>
2235
/// Adds gRPC reflection services to the specified <see cref="IServiceCollection" />.
2336
/// </summary>

src/protobuf-net.Grpc.Reflection/FileDescriptorSetFactory.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ internal static class FileDescriptorSetFactory
1717
internal static FileDescriptorSet Create(IEnumerable<Type> serviceTypes, BinderConfiguration? binderConfiguration = null)
1818
{
1919
var fileDescriptorSet = new FileDescriptorSet();
20-
var configuration = binderConfiguration ?? BinderConfiguration.Default;
20+
binderConfiguration ??= BinderConfiguration.Default;
2121

2222
foreach (var serviceType in serviceTypes)
2323
{
24-
Populate(fileDescriptorSet, serviceType, configuration);
24+
Populate(fileDescriptorSet, serviceType, binderConfiguration);
2525
}
2626

2727
fileDescriptorSet.Process();
@@ -30,14 +30,13 @@ internal static FileDescriptorSet Create(IEnumerable<Type> serviceTypes, BinderC
3030

3131
private static void Populate(FileDescriptorSet fileDescriptorSet, Type serviceType, BinderConfiguration binderConfiguration)
3232
{
33-
string? serviceName, inputFile, outputFile;
3433
var serviceContracts = typeof(IGrpcService).IsAssignableFrom(serviceType)
3534
? new HashSet<Type> { serviceType }
3635
: ContractOperation.ExpandInterfaces(serviceType);
3736

3837
foreach (var serviceContract in serviceContracts)
3938
{
40-
if (!binderConfiguration.Binder.IsServiceContract(serviceContract, out serviceName)) continue;
39+
if (!binderConfiguration.Binder.IsServiceContract(serviceContract, out string? serviceName)) continue;
4140

4241
var serviceDescriptor = new ServiceDescriptorProto
4342
{
@@ -51,8 +50,8 @@ private static void Populate(FileDescriptorSet fileDescriptorSet, Type serviceTy
5150
serviceDescriptor.Methods.Add(new MethodDescriptorProto
5251
{
5352
Name = op.Name,
54-
InputType = GetType(op.From, fileDescriptorSet, out inputFile),
55-
OutputType = GetType(op.To, fileDescriptorSet, out outputFile),
53+
InputType = GetType(binderConfiguration, op.From, fileDescriptorSet, out string? inputFile),
54+
OutputType = GetType(binderConfiguration, op.To, fileDescriptorSet, out string? outputFile),
5655
ClientStreaming = op.MethodType == MethodType.ClientStreaming ||
5756
op.MethodType == MethodType.DuplexStreaming,
5857
ServerStreaming = op.MethodType == MethodType.ServerStreaming ||
@@ -81,15 +80,17 @@ private static void Populate(FileDescriptorSet fileDescriptorSet, Type serviceTy
8180
}
8281
}
8382

84-
private static string GetType(Type type, FileDescriptorSet fileDescriptorSet, out string descriptorProto)
83+
private static string GetType(BinderConfiguration binderConfiguration, Type type, FileDescriptorSet fileDescriptorSet, out string descriptorProto)
8584
{
8685
var typeName = type.Name;
8786
var fileName = type.FullName + ".proto";
8887
var fileDescriptor = fileDescriptorSet.Files.SingleOrDefault(f => f.Name.Equals(fileName, StringComparison.Ordinal));
8988

89+
TypeModel model = binderConfiguration.TryGetFactory(type) is ProtoBufMarshallerFactory factory ? factory.Model : RuntimeTypeModel.Default;
90+
9091
if (fileDescriptor is null)
9192
{
92-
var schema = RuntimeTypeModel.Default.GetSchema(type, ProtoSyntax.Proto3);
93+
var schema = model.GetSchema(type, ProtoSyntax.Proto3);
9394

9495
using var reader = new StringReader(schema);
9596

src/protobuf-net.Grpc.Reflection/Generated/Reflection.cs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
// Input: https://github.com/grpc/grpc/blob/64fb7d47452e32e8746569bf0d1c19c5d1f1a1d9/src/proto/grpc/reflection/v1alpha/reflection.proto
55
// </auto-generated>
66

7-
#pragma warning disable CS0612, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
7+
#region Designer generated code
8+
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
89
namespace grpc.reflection.v1alpha
910
{
1011

@@ -23,8 +24,8 @@ public partial class ServerReflectionRequest : global::ProtoBuf.IExtensible
2324
[global::System.ComponentModel.DefaultValue("")]
2425
public string FileByFilename
2526
{
26-
get { return __pbn__message_request.Is(3) ? ((string)__pbn__message_request.Object) : ""; }
27-
set { __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(3, value); }
27+
get => __pbn__message_request.Is(3) ? ((string)__pbn__message_request.Object) : "";
28+
set => __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(3, value);
2829
}
2930
public bool ShouldSerializeFileByFilename() => __pbn__message_request.Is(3);
3031
public void ResetFileByFilename() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_request, 3);
@@ -35,17 +36,17 @@ public string FileByFilename
3536
[global::System.ComponentModel.DefaultValue("")]
3637
public string FileContainingSymbol
3738
{
38-
get { return __pbn__message_request.Is(4) ? ((string)__pbn__message_request.Object) : ""; }
39-
set { __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(4, value); }
39+
get => __pbn__message_request.Is(4) ? ((string)__pbn__message_request.Object) : "";
40+
set => __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(4, value);
4041
}
4142
public bool ShouldSerializeFileContainingSymbol() => __pbn__message_request.Is(4);
4243
public void ResetFileContainingSymbol() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_request, 4);
4344

4445
[global::ProtoBuf.ProtoMember(5, Name = @"file_containing_extension")]
4546
public ExtensionRequest FileContainingExtension
4647
{
47-
get { return __pbn__message_request.Is(5) ? ((ExtensionRequest)__pbn__message_request.Object) : default; }
48-
set { __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(5, value); }
48+
get => __pbn__message_request.Is(5) ? ((ExtensionRequest)__pbn__message_request.Object) : default;
49+
set => __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(5, value);
4950
}
5051
public bool ShouldSerializeFileContainingExtension() => __pbn__message_request.Is(5);
5152
public void ResetFileContainingExtension() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_request, 5);
@@ -54,8 +55,8 @@ public ExtensionRequest FileContainingExtension
5455
[global::System.ComponentModel.DefaultValue("")]
5556
public string AllExtensionNumbersOfType
5657
{
57-
get { return __pbn__message_request.Is(6) ? ((string)__pbn__message_request.Object) : ""; }
58-
set { __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(6, value); }
58+
get => __pbn__message_request.Is(6) ? ((string)__pbn__message_request.Object) : "";
59+
set => __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(6, value);
5960
}
6061
public bool ShouldSerializeAllExtensionNumbersOfType() => __pbn__message_request.Is(6);
6162
public void ResetAllExtensionNumbersOfType() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_request, 6);
@@ -64,8 +65,8 @@ public string AllExtensionNumbersOfType
6465
[global::System.ComponentModel.DefaultValue("")]
6566
public string ListServices
6667
{
67-
get { return __pbn__message_request.Is(7) ? ((string)__pbn__message_request.Object) : ""; }
68-
set { __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(7, value); }
68+
get => __pbn__message_request.Is(7) ? ((string)__pbn__message_request.Object) : "";
69+
set => __pbn__message_request = new global::ProtoBuf.DiscriminatedUnionObject(7, value);
6970
}
7071
public bool ShouldSerializeListServices() => __pbn__message_request.Is(7);
7172
public void ResetListServices() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_request, 7);
@@ -117,8 +118,8 @@ public partial class ServerReflectionResponse : global::ProtoBuf.IExtensible
117118
[global::ProtoBuf.ProtoMember(4, Name = @"file_descriptor_response")]
118119
public FileDescriptorResponse FileDescriptorResponse
119120
{
120-
get { return __pbn__message_response.Is(4) ? ((FileDescriptorResponse)__pbn__message_response.Object) : default; }
121-
set { __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(4, value); }
121+
get => __pbn__message_response.Is(4) ? ((FileDescriptorResponse)__pbn__message_response.Object) : default;
122+
set => __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(4, value);
122123
}
123124
public bool ShouldSerializeFileDescriptorResponse() => __pbn__message_response.Is(4);
124125
public void ResetFileDescriptorResponse() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_response, 4);
@@ -128,26 +129,26 @@ public FileDescriptorResponse FileDescriptorResponse
128129
[global::ProtoBuf.ProtoMember(5, Name = @"all_extension_numbers_response")]
129130
public ExtensionNumberResponse AllExtensionNumbersResponse
130131
{
131-
get { return __pbn__message_response.Is(5) ? ((ExtensionNumberResponse)__pbn__message_response.Object) : default; }
132-
set { __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(5, value); }
132+
get => __pbn__message_response.Is(5) ? ((ExtensionNumberResponse)__pbn__message_response.Object) : default;
133+
set => __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(5, value);
133134
}
134135
public bool ShouldSerializeAllExtensionNumbersResponse() => __pbn__message_response.Is(5);
135136
public void ResetAllExtensionNumbersResponse() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_response, 5);
136137

137138
[global::ProtoBuf.ProtoMember(6, Name = @"list_services_response")]
138139
public ListServiceResponse ListServicesResponse
139140
{
140-
get { return __pbn__message_response.Is(6) ? ((ListServiceResponse)__pbn__message_response.Object) : default; }
141-
set { __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(6, value); }
141+
get => __pbn__message_response.Is(6) ? ((ListServiceResponse)__pbn__message_response.Object) : default;
142+
set => __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(6, value);
142143
}
143144
public bool ShouldSerializeListServicesResponse() => __pbn__message_response.Is(6);
144145
public void ResetListServicesResponse() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_response, 6);
145146

146147
[global::ProtoBuf.ProtoMember(7, Name = @"error_response")]
147148
public ErrorResponse ErrorResponse
148149
{
149-
get { return __pbn__message_response.Is(7) ? ((ErrorResponse)__pbn__message_response.Object) : default; }
150-
set { __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(7, value); }
150+
get => __pbn__message_response.Is(7) ? ((ErrorResponse)__pbn__message_response.Object) : default;
151+
set => __pbn__message_response = new global::ProtoBuf.DiscriminatedUnionObject(7, value);
151152
}
152153
public bool ShouldSerializeErrorResponse() => __pbn__message_response.Is(7);
153154
public void ResetErrorResponse() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__message_response, 7);
@@ -242,4 +243,5 @@ public interface IServerReflection
242243

243244
}
244245

245-
#pragma warning restore CS0612, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
246+
#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
247+
#endregion

src/protobuf-net.Grpc.Reflection/ReflectionService.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,33 @@
1010

1111
namespace ProtoBuf.Grpc.Reflection
1212
{
13+
/// <summary>
14+
/// Implements the <see cref="IServerReflection"/> API
15+
/// </summary>
1316
public sealed class ReflectionService : IServerReflection
1417
{
1518
private readonly List<string> _services;
1619
private readonly SymbolRegistry _symbolRegistry;
1720

21+
/// <summary>
22+
/// Creates a new <see cref="ReflectionService"/> instance
23+
/// </summary>
1824
public ReflectionService(params Type[] types)
1925
: this(null, types)
2026
{
2127
}
2228

29+
/// <summary>
30+
/// Creates a new <see cref="ReflectionService"/> instance
31+
/// </summary>
2332
public ReflectionService(BinderConfiguration? binderConfiguration, params Type[] types)
2433
: this(FileDescriptorSetFactory.Create(types, binderConfiguration))
2534
{
2635
}
2736

37+
/// <summary>
38+
/// Creates a new <see cref="ReflectionService"/> instance
39+
/// </summary>
2840
public ReflectionService(
2941
FileDescriptorSet fileDescriptorSet)
3042
{
@@ -35,7 +47,7 @@ public ReflectionService(
3547
_symbolRegistry = SymbolRegistry.FromFiles(fileDescriptorSet);
3648
}
3749

38-
public async IAsyncEnumerable<ServerReflectionResponse> ServerReflectionInfoAsync(IAsyncEnumerable<ServerReflectionRequest> requests, CallContext context = default)
50+
async IAsyncEnumerable<ServerReflectionResponse> IServerReflection.ServerReflectionInfoAsync(IAsyncEnumerable<ServerReflectionRequest> requests, CallContext context)
3951
{
4052
await foreach(var request in requests)
4153
{
@@ -44,22 +56,13 @@ public async IAsyncEnumerable<ServerReflectionResponse> ServerReflectionInfoAsyn
4456
}
4557
}
4658

47-
private ServerReflectionResponse ProcessRequest(ServerReflectionRequest request)
59+
private ServerReflectionResponse ProcessRequest(ServerReflectionRequest request) => request.MessageRequestCase switch
4860
{
49-
switch (request.MessageRequestCase)
50-
{
51-
case ServerReflectionRequest.MessageRequestOneofCase.FileByFilename:
52-
return FileByFilename(request.FileByFilename);
53-
case ServerReflectionRequest.MessageRequestOneofCase.FileContainingSymbol:
54-
return FileContainingSymbol(request.FileContainingSymbol);
55-
case ServerReflectionRequest.MessageRequestOneofCase.ListServices:
56-
return ListServices();
57-
case ServerReflectionRequest.MessageRequestOneofCase.AllExtensionNumbersOfType:
58-
case ServerReflectionRequest.MessageRequestOneofCase.FileContainingExtension:
59-
default:
60-
return CreateErrorResponse(StatusCode.Unimplemented, "Request type not supported by C# reflection service.");
61-
}
62-
}
61+
ServerReflectionRequest.MessageRequestOneofCase.FileByFilename => FileByFilename(request.FileByFilename),
62+
ServerReflectionRequest.MessageRequestOneofCase.FileContainingSymbol => FileContainingSymbol(request.FileContainingSymbol),
63+
ServerReflectionRequest.MessageRequestOneofCase.ListServices => ListServices(),
64+
_ => CreateErrorResponse(StatusCode.Unimplemented, "Request type not supported by C# reflection service."),
65+
};
6366

6467
private ServerReflectionResponse FileByFilename(string filename)
6568
{

src/protobuf-net.Grpc/Configuration/BinderConfiguration.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,7 @@ public static BinderConfiguration Create(IList<MarshallerFactory>? marshallerFac
5353
/// </summary>
5454
/// <param name="marshaller">The marshaller to use - if null, the cache is reset for this type</param>
5555
public void SetMarshaller<T>(Marshaller<T>? marshaller) => MarshallerCache.SetMarshaller<T>(marshaller);
56+
57+
internal MarshallerFactory? TryGetFactory(Type type) => MarshallerCache.TryGetFactory(type);
5658
}
5759
}

src/protobuf-net.Grpc/Configuration/ProtoBufMarshallerFactory.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public enum Options
3939
/// </summary>
4040
public static MarshallerFactory Default { get; } = new ProtoBufMarshallerFactory(RuntimeTypeModel.Default, Options.None, default);
4141

42+
/// <summary>
43+
/// Gets the model used by this instance.
44+
/// </summary>
45+
public TypeModel Model => _model;
46+
4247
private readonly TypeModel _model;
4348
private readonly SerializationContext? _userState;
4449
private readonly Options _options;

src/protobuf-net.Grpc/Internal/MarshallerCache.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,15 @@ internal void SetMarshaller<T>(Marshaller<T>? marshaller)
6767
}
6868
return null;
6969
}
70+
71+
internal MarshallerFactory? TryGetFactory(Type type)
72+
{
73+
foreach (var factory in _factories)
74+
{
75+
if (factory.CanSerialize(type))
76+
return factory;
77+
}
78+
return null;
79+
}
7080
}
7181
}

0 commit comments

Comments
 (0)