Skip to content

Commit 5cb623c

Browse files
authored
Update gRPC shared code (#62340)
1 parent 01e4408 commit 5cb623c

18 files changed

+267
-98
lines changed

src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/GrpcJsonTranscodingServiceExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Grpc.AspNetCore.Server;
55
using Grpc.AspNetCore.Server.Model;
66
using Grpc.Shared;
7+
using Grpc.Shared.Server;
78
using Microsoft.AspNetCore.Grpc.JsonTranscoding;
89
using Microsoft.AspNetCore.Grpc.JsonTranscoding.Internal.Binding;
910
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -28,6 +29,7 @@ public static IGrpcServerBuilder AddJsonTranscoding(this IGrpcServerBuilder buil
2829
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IServiceMethodProvider<>), typeof(JsonTranscodingServiceMethodProvider<>)));
2930
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<GrpcJsonTranscodingOptions>, GrpcJsonTranscodingOptionsSetup>());
3031
builder.Services.TryAddSingleton<DescriptorRegistry>();
32+
builder.Services.TryAddSingleton<InterceptorActivators>();
3133

3234
return builder;
3335
}

src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/Internal/Binding/JsonTranscodingProviderServiceBinder.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ private delegate (RequestDelegate RequestDelegate, List<object> Metadata) Create
3434
private readonly GrpcServiceOptions<TService> _serviceOptions;
3535
private readonly IGrpcServiceActivator<TService> _serviceActivator;
3636
private readonly GrpcJsonTranscodingOptions _jsonTranscodingOptions;
37+
private readonly InterceptorActivators _interceptorActivators;
3738
private readonly ILoggerFactory _loggerFactory;
3839
private readonly ILogger _logger;
3940

@@ -45,7 +46,8 @@ internal JsonTranscodingProviderServiceBinder(
4546
GrpcServiceOptions<TService> serviceOptions,
4647
ILoggerFactory loggerFactory,
4748
IGrpcServiceActivator<TService> serviceActivator,
48-
GrpcJsonTranscodingOptions jsonTranscodingOptions)
49+
GrpcJsonTranscodingOptions jsonTranscodingOptions,
50+
InterceptorActivators interceptorActivators)
4951
{
5052
_context = context;
5153
_invokerResolver = invokerResolver;
@@ -54,6 +56,7 @@ internal JsonTranscodingProviderServiceBinder(
5456
_serviceOptions = serviceOptions;
5557
_serviceActivator = serviceActivator;
5658
_jsonTranscodingOptions = jsonTranscodingOptions;
59+
_interceptorActivators = interceptorActivators;
5760
_loggerFactory = loggerFactory;
5861
_logger = loggerFactory.CreateLogger<JsonTranscodingProviderServiceBinder<TService>>();
5962
}
@@ -162,7 +165,7 @@ private void ProcessHttpRule<TRequest, TResponse>(
162165
httpRule,
163166
methodDescriptor);
164167

165-
var methodInvoker = new UnaryServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, methodOptions, _serviceActivator);
168+
var methodInvoker = new UnaryServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, methodOptions, _serviceActivator, _interceptorActivators);
166169
var callHandler = new UnaryServerCallHandler<TService, TRequest, TResponse>(
167170
methodInvoker,
168171
_loggerFactory,
@@ -189,7 +192,7 @@ private void ProcessHttpRule<TRequest, TResponse>(
189192
httpRule,
190193
methodDescriptor);
191194

192-
var methodInvoker = new ServerStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, methodOptions, _serviceActivator);
195+
var methodInvoker = new ServerStreamingServerMethodInvoker<TService, TRequest, TResponse>(invoker, method, methodOptions, _serviceActivator, _interceptorActivators);
193196
var callHandler = new ServerStreamingServerCallHandler<TService, TRequest, TResponse>(
194197
methodInvoker,
195198
_loggerFactory,

src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/Internal/Binding/JsonTranscodingServiceMethodProvider.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ internal sealed partial class JsonTranscodingServiceMethodProvider<TService> : I
2020
private readonly ILoggerFactory _loggerFactory;
2121
private readonly IGrpcServiceActivator<TService> _serviceActivator;
2222
private readonly DescriptorRegistry _serviceDescriptorRegistry;
23+
private readonly InterceptorActivators _interceptorActivators;
2324

2425
public JsonTranscodingServiceMethodProvider(
2526
ILoggerFactory loggerFactory,
2627
IOptions<GrpcServiceOptions> globalOptions,
2728
IOptions<GrpcServiceOptions<TService>> serviceOptions,
2829
IGrpcServiceActivator<TService> serviceActivator,
2930
IOptions<GrpcJsonTranscodingOptions> jsonTranscodingOptions,
30-
DescriptorRegistry serviceDescriptorRegistry)
31+
DescriptorRegistry serviceDescriptorRegistry,
32+
InterceptorActivators interceptorActivators)
3133
{
3234
_logger = loggerFactory.CreateLogger<JsonTranscodingServiceMethodProvider<TService>>();
3335
_globalOptions = globalOptions.Value;
@@ -36,6 +38,7 @@ public JsonTranscodingServiceMethodProvider(
3638
_loggerFactory = loggerFactory;
3739
_serviceActivator = serviceActivator;
3840
_serviceDescriptorRegistry = serviceDescriptorRegistry;
41+
_interceptorActivators = interceptorActivators;
3942
}
4043

4144
public void OnServiceMethodDiscovery(ServiceMethodProviderContext<TService> context)
@@ -70,7 +73,8 @@ public void OnServiceMethodDiscovery(ServiceMethodProviderContext<TService> cont
7073
_serviceOptions,
7174
_loggerFactory,
7275
_serviceActivator,
73-
_jsonTranscodingOptions);
76+
_jsonTranscodingOptions,
77+
_interceptorActivators);
7478

7579
try
7680
{

src/Grpc/JsonTranscoding/src/Microsoft.AspNetCore.Grpc.JsonTranscoding/Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<Description>HTTP API for gRPC ASP.NET Core</Description>
44
<PackageTags>gRPC RPC HTTP/2 REST</PackageTags>
@@ -18,6 +18,8 @@
1818
<Compile Include="..\Shared\Server\ServerMethodInvokerBase.cs" Link="Internal\Shared\Server\ServerMethodInvokerBase.cs" />
1919
<Compile Include="..\Shared\Server\ServerStreamingServerMethodInvoker.cs" Link="Internal\Shared\Server\ServerStreamingServerMethodInvoker.cs" />
2020
<Compile Include="..\Shared\Server\UnaryServerMethodInvoker.cs" Link="Internal\Shared\Server\UnaryServerMethodInvoker.cs" />
21+
<Compile Include="..\Shared\Server\ServerDynamicAccessConstants.cs" Link="Internal\Shared\Server\ServerDynamicAccessConstants.cs" />
22+
<Compile Include="..\Shared\Server\InterceptorActivators.cs" Link="Internal\Shared\Server\InterceptorActivators.cs" />
2123
<Compile Include="..\Shared\DescriptorRegistry.cs" Link="Internal\Shared\DescriptorRegistry.cs" />
2224
<Compile Include="..\Shared\AuthContextHelpers.cs" Link="Internal\Shared\AuthContextHelpers.cs" />
2325
<Compile Include="..\Shared\ServiceDescriptorHelpers.cs" Link="Internal\Shared\ServiceDescriptorHelpers.cs" />

src/Grpc/JsonTranscoding/src/Shared/Server/BindMethodFinder.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#endregion
1818

19+
using System.Diagnostics.CodeAnalysis;
1920
using System.Reflection;
2021
using Grpc.Core;
2122

@@ -64,6 +65,8 @@ internal static class BindMethodFinder
6465
return null;
6566
}
6667

68+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
69+
Justification = "Fallback doesn't have BindServiceMethodAttribute so can't be verified.")]
6770
internal static MethodInfo? GetBindMethodFallback(Type serviceType)
6871
{
6972
// Search for the generated service base class

src/Grpc/JsonTranscoding/src/Shared/Server/ClientStreamingServerMethodInvoker.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#endregion
1818

19+
using System.Diagnostics.CodeAnalysis;
1920
using Grpc.AspNetCore.Server;
2021
using Grpc.AspNetCore.Server.Model;
2122
using Grpc.Core;
@@ -29,7 +30,7 @@ namespace Grpc.Shared.Server;
2930
/// <typeparam name="TService">Service type for this method.</typeparam>
3031
/// <typeparam name="TRequest">Request message type for this method.</typeparam>
3132
/// <typeparam name="TResponse">Response message type for this method.</typeparam>
32-
internal sealed class ClientStreamingServerMethodInvoker<TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
33+
internal sealed class ClientStreamingServerMethodInvoker<[DynamicallyAccessedMembers(ServerDynamicAccessConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
3334
where TRequest : class
3435
where TResponse : class
3536
where TService : class
@@ -44,18 +45,20 @@ internal sealed class ClientStreamingServerMethodInvoker<TService, TRequest, TRe
4445
/// <param name="method">The description of the gRPC method.</param>
4546
/// <param name="options">The options used to execute the method.</param>
4647
/// <param name="serviceActivator">The service activator used to create service instances.</param>
48+
/// <param name="interceptorActivators">The interceptor activators used to create interceptor instances.</param>
4749
public ClientStreamingServerMethodInvoker(
4850
ClientStreamingServerMethod<TService, TRequest, TResponse> invoker,
4951
Method<TRequest, TResponse> method,
5052
MethodOptions options,
51-
IGrpcServiceActivator<TService> serviceActivator)
53+
IGrpcServiceActivator<TService> serviceActivator,
54+
InterceptorActivators interceptorActivators)
5255
: base(method, options, serviceActivator)
5356
{
5457
_invoker = invoker;
5558

5659
if (Options.HasInterceptors)
5760
{
58-
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors);
61+
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors, interceptorActivators);
5962
_pipelineInvoker = interceptorPipeline.ClientStreamingPipeline(ResolvedInterceptorInvoker);
6063
}
6164
}
@@ -65,7 +68,7 @@ private async Task<TResponse> ResolvedInterceptorInvoker(IAsyncStreamReader<TReq
6568
GrpcActivatorHandle<TService> serviceHandle = default;
6669
try
6770
{
68-
serviceHandle = ServiceActivator.Create(resolvedContext.GetHttpContext().RequestServices);
71+
serviceHandle = CreateServiceHandle(resolvedContext);
6972
return await _invoker(
7073
serviceHandle.Instance,
7174
requestStream,
@@ -95,7 +98,7 @@ public async Task<TResponse> Invoke(HttpContext httpContext, ServerCallContext s
9598
GrpcActivatorHandle<TService> serviceHandle = default;
9699
try
97100
{
98-
serviceHandle = ServiceActivator.Create(httpContext.RequestServices);
101+
serviceHandle = CreateServiceHandle(httpContext);
99102
return await _invoker(
100103
serviceHandle.Instance,
101104
requestStream,

src/Grpc/JsonTranscoding/src/Shared/Server/DuplexStreamingServerMethodInvoker.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#endregion
1818

19+
using System.Diagnostics.CodeAnalysis;
1920
using Grpc.AspNetCore.Server;
2021
using Grpc.AspNetCore.Server.Model;
2122
using Grpc.Core;
@@ -29,7 +30,7 @@ namespace Grpc.Shared.Server;
2930
/// <typeparam name="TService">Service type for this method.</typeparam>
3031
/// <typeparam name="TRequest">Request message type for this method.</typeparam>
3132
/// <typeparam name="TResponse">Response message type for this method.</typeparam>
32-
internal sealed class DuplexStreamingServerMethodInvoker<TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
33+
internal sealed class DuplexStreamingServerMethodInvoker<[DynamicallyAccessedMembers(ServerDynamicAccessConstants.ServiceAccessibility)] TService, TRequest, TResponse> : ServerMethodInvokerBase<TService, TRequest, TResponse>
3334
where TRequest : class
3435
where TResponse : class
3536
where TService : class
@@ -44,18 +45,20 @@ internal sealed class DuplexStreamingServerMethodInvoker<TService, TRequest, TRe
4445
/// <param name="method">The description of the gRPC method.</param>
4546
/// <param name="options">The options used to execute the method.</param>
4647
/// <param name="serviceActivator">The service activator used to create service instances.</param>
48+
/// <param name="interceptorActivators">The interceptor activators used to create interceptor instances.</param>
4749
public DuplexStreamingServerMethodInvoker(
4850
DuplexStreamingServerMethod<TService, TRequest, TResponse> invoker,
4951
Method<TRequest, TResponse> method,
5052
MethodOptions options,
51-
IGrpcServiceActivator<TService> serviceActivator)
53+
IGrpcServiceActivator<TService> serviceActivator,
54+
InterceptorActivators interceptorActivators)
5255
: base(method, options, serviceActivator)
5356
{
5457
_invoker = invoker;
5558

5659
if (Options.HasInterceptors)
5760
{
58-
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors);
61+
var interceptorPipeline = new InterceptorPipelineBuilder<TRequest, TResponse>(Options.Interceptors, interceptorActivators);
5962
_pipelineInvoker = interceptorPipeline.DuplexStreamingPipeline(ResolvedInterceptorInvoker);
6063
}
6164
}
@@ -65,7 +68,7 @@ private async Task ResolvedInterceptorInvoker(IAsyncStreamReader<TRequest> reque
6568
GrpcActivatorHandle<TService> serviceHandle = default;
6669
try
6770
{
68-
serviceHandle = ServiceActivator.Create(resolvedContext.GetHttpContext().RequestServices);
71+
serviceHandle = CreateServiceHandle(resolvedContext);
6972
await _invoker(
7073
serviceHandle.Instance,
7174
requestStream,
@@ -88,15 +91,15 @@ await _invoker(
8891
/// <param name="serverCallContext">The <see cref="ServerCallContext"/>.</param>
8992
/// <param name="requestStream">The <typeparamref name="TRequest"/> reader.</param>
9093
/// <param name="responseStream">The <typeparamref name="TResponse"/> writer.</param>
91-
/// <returns>A <see cref="Task"/> that represents the asynchronous method.</returns>
94+
/// <returns>A <see cref="Task{TResponse}"/> that represents the asynchronous method.</returns>
9295
public async Task Invoke(HttpContext httpContext, ServerCallContext serverCallContext, IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream)
9396
{
9497
if (_pipelineInvoker == null)
9598
{
9699
GrpcActivatorHandle<TService> serviceHandle = default;
97100
try
98101
{
99-
serviceHandle = ServiceActivator.Create(httpContext.RequestServices);
102+
serviceHandle = CreateServiceHandle(httpContext);
100103
await _invoker(
101104
serviceHandle.Instance,
102105
requestStream,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#region Copyright notice and license
2+
3+
// Copyright 2019 The gRPC Authors
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
#endregion
18+
19+
using System.Collections.Concurrent;
20+
using System.Diagnostics.CodeAnalysis;
21+
using Grpc.AspNetCore.Server;
22+
using Microsoft.Extensions.DependencyInjection;
23+
24+
namespace Grpc.Shared.Server;
25+
26+
internal sealed class InterceptorActivators
27+
{
28+
private readonly ConcurrentDictionary<Type, IGrpcInterceptorActivator> _cachedActivators = new();
29+
private readonly IServiceProvider _serviceProvider;
30+
31+
public InterceptorActivators(IServiceProvider serviceProvider)
32+
{
33+
_serviceProvider = serviceProvider;
34+
}
35+
36+
public IGrpcInterceptorActivator GetInterceptorActivator(Type type)
37+
{
38+
return _cachedActivators.GetOrAdd<IServiceProvider>(type, CreateActivator, _serviceProvider);
39+
}
40+
41+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
42+
Justification = "Type parameter members are preserved with DynamicallyAccessedMembers on InterceptorRegistration.Type property.")]
43+
[UnconditionalSuppressMessage("AotAnalysis", "IL3050:RequiresDynamicCode",
44+
Justification = "Type definition is explicitly specified and type argument is always an Interceptor type.")]
45+
private static IGrpcInterceptorActivator CreateActivator(Type type, IServiceProvider serviceProvider)
46+
{
47+
return (IGrpcInterceptorActivator)serviceProvider.GetRequiredService(typeof(IGrpcInterceptorActivator<>).MakeGenericType(type));
48+
}
49+
}

0 commit comments

Comments
 (0)