| File: Internal\Binding\JsonTranscodingServiceMethodProvider.cs | Web Access |
| Project: src\aspnetcore\src\Grpc\JsonTranscoding\src\Microsoft.AspNetCore.Grpc.JsonTranscoding\Microsoft.AspNetCore.Grpc.JsonTranscoding.csproj (Microsoft.AspNetCore.Grpc.JsonTranscoding) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Google.Protobuf.Reflection; using Grpc.AspNetCore.Server; using Grpc.AspNetCore.Server.Model; using Grpc.Shared; using Grpc.Shared.Server; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Grpc.JsonTranscoding.Internal.Binding; internal sealed partial class JsonTranscodingServiceMethodProvider<TService> : IServiceMethodProvider<TService> where TService : class { private readonly ILogger<JsonTranscodingServiceMethodProvider<TService>> _logger; private readonly GrpcServiceOptions _globalOptions; private readonly GrpcServiceOptions<TService> _serviceOptions; private readonly GrpcJsonTranscodingOptions _jsonTranscodingOptions; private readonly ILoggerFactory _loggerFactory; private readonly IGrpcServiceActivator<TService> _serviceActivator; private readonly DescriptorRegistry _serviceDescriptorRegistry; private readonly InterceptorActivators _interceptorActivators; public JsonTranscodingServiceMethodProvider( ILoggerFactory loggerFactory, IOptions<GrpcServiceOptions> globalOptions, IOptions<GrpcServiceOptions<TService>> serviceOptions, IGrpcServiceActivator<TService> serviceActivator, IOptions<GrpcJsonTranscodingOptions> jsonTranscodingOptions, DescriptorRegistry serviceDescriptorRegistry, InterceptorActivators interceptorActivators) { _logger = loggerFactory.CreateLogger<JsonTranscodingServiceMethodProvider<TService>>(); _globalOptions = globalOptions.Value; _serviceOptions = serviceOptions.Value; _jsonTranscodingOptions = jsonTranscodingOptions.Value; _loggerFactory = loggerFactory; _serviceActivator = serviceActivator; _serviceDescriptorRegistry = serviceDescriptorRegistry; _interceptorActivators = interceptorActivators; } public void OnServiceMethodDiscovery(ServiceMethodProviderContext<TService> context) { var bindMethodInfo = BindMethodFinder.GetBindMethod(typeof(TService)); // Invoke BindService(ServiceBinderBase, BaseType) if (bindMethodInfo != null) { // The second parameter is always the service base type var serviceParameter = bindMethodInfo.GetParameters()[1]; ServiceDescriptor? serviceDescriptor = null; try { serviceDescriptor = ServiceDescriptorHelpers.GetServiceDescriptor(bindMethodInfo.DeclaringType!); } catch (Exception ex) { Log.ServiceDescriptorError(_logger, typeof(TService), ex); } if (serviceDescriptor != null) { _serviceDescriptorRegistry.RegisterFileDescriptor(serviceDescriptor.File); var binder = new JsonTranscodingProviderServiceBinder<TService>( context, new ReflectionServiceInvokerResolver<TService>(serviceParameter.ParameterType), serviceDescriptor, _globalOptions, _serviceOptions, _loggerFactory, _serviceActivator, _jsonTranscodingOptions, _interceptorActivators); try { bindMethodInfo.Invoke(null, new object?[] { binder, null }); } catch (Exception ex) { throw new InvalidOperationException($"Error binding gRPC service '{typeof(TService).Name}'.", ex); } } } else { Log.BindMethodNotFound(_logger, typeof(TService)); } } private static partial class Log { [LoggerMessage(1, LogLevel.Warning, "Could not find bind method for {ServiceType}.", EventName = "BindMethodNotFound")] public static partial void BindMethodNotFound(ILogger logger, Type serviceType); [LoggerMessage(2, LogLevel.Warning, "Error getting service descriptor for {ServiceType}.", EventName = "ServiceDescriptorError")] public static partial void ServiceDescriptorError(ILogger logger, Type serviceType, Exception ex); } }