You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like the FlightClient to support standard integration with the Grpc.Net.ClientFactory library.
Background
It is standard in .NET web applications to manage gRPC clients using the Grpc.Net.ClientFactory, particularly when using the ASP.NET Core framework.
Currently the FlightClient does not work out of the box with the Grpc.Net.ClientFactory library. This is because the FlightClient is a thin abstraction over the raw .NET gRPC client, and does not have all of the same constructors as the raw gRPC client. Specifically, the Grpc.Net.ClientFactory expects a constructor that accepts a CallInvoker.
Steps to reproduce:
Update the Apache.Arrow.Flight.Tests package with the following library: dotnet add package Grpc.Net.ClientFactory.
Add the following test class, which attempts to instantiate a FlightClient instance using the Grpc.Net.ClientFactory library, and view the test fails with the following error.
System.InvalidOperationException
A suitable constructor for type 'Apache.Arrow.Flight.Client.FlightClient' could not be located. Ensure the type is concrete and all parameters of a public constructor are either registered as services or passed as arguments. Also ensure no extraneous arguments are provided.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& matchingParameterMap)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactoryInternal(Type instanceType, Type[] argumentTypes, ParameterExpression& provider, ParameterExpression& argumentArray, Expression& factoryExpressionBody)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type instanceType, Type[] argumentTypes)
at Grpc.Net.ClientFactory.Internal.DefaultClientActivator`1.<>c.<.cctor>b__9_0()
at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
at Grpc.Net.ClientFactory.Internal.DefaultClientActivator`1.get_Activator()
at Grpc.Net.ClientFactory.Internal.DefaultClientActivator`1.CreateClient(CallInvoker callInvoker)
at Grpc.Net.ClientFactory.Internal.DefaultGrpcClientFactory.CreateClient[TClient](String name)
at Microsoft.Extensions.DependencyInjection.GrpcClientServiceExtensions.<>c__DisplayClass7_0`1.<AddGrpcHttpClient>b__0(IServiceProvider s)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Apache.Arrow.Flight.Tests.GrpcNetClientFactoryTests.CanResolve_FlightClient_UsingGrpcClientFactory() in C:\Sourcecode\arrow\csharp\test\Apache.Arrow.Flight.Tests\GrpcNetClientFactoryTests.cs:line 24
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Proposed Solution
This can be achieved by adding another constructor to the FlightClient like below. I would be happy to open a pull request for this (along with test coverage) if this proposal is accepted.
Another solution could be to create an internal constructor that accepts an instance of FlightService.FlightServiceClient, and have a client extension library, which has more decoupling between the FlightClient and Grpc.Net.ClientFactory, but has a larger surface area. However, gRPC interceptors are attached at the CallInvoker level, so it is probably desirable to accept a constructor with a CallInvoker regardless.
Component(s)
C#
The text was updated successfully, but these errors were encountered:
Describe the enhancement requested
Request
I would like the
FlightClient
to support standard integration with theGrpc.Net.ClientFactory
library.Background
It is standard in .NET web applications to manage gRPC clients using the Grpc.Net.ClientFactory, particularly when using the ASP.NET Core framework.
Currently the
FlightClient
does not work out of the box with theGrpc.Net.ClientFactory
library. This is because theFlightClient
is a thin abstraction over the raw .NET gRPC client, and does not have all of the same constructors as the raw gRPC client. Specifically, theGrpc.Net.ClientFactory
expects a constructor that accepts aCallInvoker
.Steps to reproduce:
Update the
Apache.Arrow.Flight.Tests
package with the following library:dotnet add package Grpc.Net.ClientFactory
.Add the following test class, which attempts to instantiate a
FlightClient
instance using theGrpc.Net.ClientFactory
library, and view the test fails with the following error.Proposed Solution
This can be achieved by adding another constructor to the
FlightClient
like below. I would be happy to open a pull request for this (along with test coverage) if this proposal is accepted.Another solution could be to create an internal constructor that accepts an instance of
FlightService.FlightServiceClient
, and have a client extension library, which has more decoupling between theFlightClient
andGrpc.Net.ClientFactory
, but has a larger surface area. However, gRPC interceptors are attached at theCallInvoker
level, so it is probably desirable to accept a constructor with aCallInvoker
regardless.Component(s)
C#
The text was updated successfully, but these errors were encountered: