ServiceModel.Grpc.Emit OperationDescriptorBuilder не содержит ctor с двумя параметрами в образе Docker LinuxC#

Место общения программистов C#
Ответить
Anonymous
 ServiceModel.Grpc.Emit OperationDescriptorBuilder не содержит ctor с двумя параметрами в образе Docker Linux

Сообщение Anonymous »

Использование последней версии ServiceModel.Grpc для сервера и клиента из https://github.com/max-ieremенко/Servic ... tag/1.11.1
Контракт на обслуживание:
[ServiceContract]
public interface ITestService
{
[OperationContract]
Task
PingAsync();
}

Реализация:
public partial class TestService : ITestService
{
public async Task
PingAsync()
{
return new PingReply
{
Message = "TestService Service is Available",
Status = "Success",
};
}
}

Запуск на стороне сервера:
builder.Services.AddServiceModelGrpc();
builder.Services.AddScoped();
.
.
.
app.MapGrpcService().EnableGrpcWeb().RequireCors("AllowGrpc");

Запуск клиента Blazor:
builder.Services
.AddGrpcClientEx()
.AddSingleton(provider =>
{
var baseAddress = provider.GetRequiredService().BaseAddress;
var httpHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
return GrpcChannel.ForAddress(baseAddress, new GrpcChannelOptions { HttpHandler = httpHandler, UnsafeUseInsecureChannelCallCredentials = true, ThrowOperationCanceledOnCancellation = false });
})
.AddSingleton(_ => new ClientFactory());

и имп AddGrpcCleintEx:
public static IServiceCollection AddGrpcClientEx(this IServiceCollection services) where T : class
{
return services.AddScoped(provider =>
{
var channel = provider.GetRequiredService();
return provider.GetRequiredService().CreateClient(channel);
});
}

Вызов метода Ping на стороне клиента (Webassembly Blazor):
var service = ServiceLocator.ServiceProvider.GetRequiredService();
var ret = await service.PingAsync();

В режиме разработки проблем нет, но когда я развертываю его как образ Docker в Linux, возникает следующее исключение:

Компонент отрисовки необработанных исключений: OperationDescriptorBuilder не содержит ctor с 2 параметрами.
System.ArgumentException: OperationDescriptorBuilder не содержит ctor с 2 параметрами.
at ServiceModel.Grpc.Emit.ReflectionTools.Constructor(тип типа, параметры Int32Count)
в ServiceModel.Grpc.Emit.CodeGenerators.ReflectDescriptor..ctor()
в ServiceModel.Grpc.Emit.CodeGenerators.EmitContractBuilder. Сборка (ModuleBuilder, ModuleBuilder, ContractDescription1 description, String className) at ServiceModel.Grpc.Emit.EmitGenerator.GenerateContract(Type serviceType, ILogger logger) at ServiceModel.Grpc.Emit.EmitGenerator.GenerateClientBuilder[ITestService](ILogger logger) at ServiceModel.Grpc.Client.ClientRegistration.EmitBuilder[ITestService](ILogger ) at ServiceModel.Grpc.Client.ClientRegistration.Build[ITestService](IClientBuilder1, ServiceModelGrpcClientOptions, Действие1 ) at ServiceModel.Grpc.Client.ClientFactory.RegisterClient[ITestService](IClientBuilder1 , Действие1 , Boolean ) at ServiceModel.Grpc.Client.ClientFactory.CreateClient[ITestService](CallInvoker ) at ServiceModel.Grpc.Client.ClientFactory.CreateClient[ITestService](ChannelBase ) at ServiceModel.Grpc.Client.GrpcClientExtensions.c__01[[Server.ITestService, Server.Infra, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].b__0_0(поставщик IServiceProvider)
в Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver .VisitFactory(FactoryCallSite, RuntimeResolverContext)
в Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite , RuntimeResolverContext ) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite , RuntimeResolverContext , ServiceProviderEngineScope , RuntimeResolverLock ) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite , RuntimeResolverContext ) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version =8.0.0.0, Культура=нейтральная, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, аргумент RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite, ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.c__DisplayClass4_0.b__0(область ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier, ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type )
в Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider , Type )
в Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredServiceITestService

но я провел некоторые исследования по журналу и отладке и не знаю, почему в режиме разработки метод ниже будет вызываться из ReflectionTools из ServiceModel.Grpc.Emit< /code> как:
public static ConstructorInfo Constructor(this Type type, params Type[] parameters)

но в режиме производства докера, указанный ниже, метод отражения выдает это исключение:
public static ConstructorInfo Constructor(this Type type, int parametersCount)

Обновление 1:
стек режима разработки выглядит примерно так:

Стек вызовов в System.Environment.get_StackTrace()
в ServiceModel.Grpc.Emit.ReflectionTools.Constructor (тип типа, параметры типа[]) в x\ReflectionTools.cs: строка 142
в ServiceModel.Grpc.Emit.CodeGenerators.EmitContractBuilder.Build(ModuleBuilder ModuleBuilder, описание ContractDescription`1, String className) в x\ServiceModel.Grpc.Emit\CodeGenerators\EmitContractBuilder.cs :строка 57
в ServiceModel.Grpc.Emit.EmitGenerator.GenerateContract(Type serviceType, регистратор ILogger) в x\ServiceModel.Grpc.Emit\EmitGenerator.cs:строка 116
в ServiceModel.Grpc.Emit.EmitGenerator.GenerateClientBuilder[IRoleService](ILogger) регистратор) в x\ServiceModel.Grpc.Emit\EmitGenerator.cs:строка 37
в ServiceModel.Grpc.Client.ClientRegistration.EmitBuilder[IRoleService](регистратор ILogger) в x\ServiceModel.Grpc\Client\ClientRegistration.cs:line 105

реализация ReflectDescriptor подобен приведенному ниже, что означает, что один из этих Constructor(2) выдаст exp, но почему он работает в режиме разработки и в режиме Windows, но не работает в докере Linux.
public ReflectDescriptor()
{
FuncMethodInfoCtor = typeof(Func).Constructor(2);

BuilderCtor = typeof(OperationDescriptorBuilder).Constructor(2);
BuilderBuild = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.Build));
BuilderWithRequest = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithRequest));
BuilderWithResponse = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithResponse));
BuilderWithRequestHeaderParameters = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithRequestHeaderParameters));
BuilderWithRequestParameters = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithRequestParameters));
BuilderWithRequestStream = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithRequestStream));
BuilderWithResponseStream = typeof(OperationDescriptorBuilder).InstanceMethod(nameof(OperationDescriptorBuilder.WithResponseStream));

_createMessageAccessor = new Dictionary();
CreateStreamAccessor = null!;
foreach (var method in typeof(AccessorsFactory).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly))
{
if (method.Name == nameof(AccessorsFactory.CreateMessageAccessor))
{
var args = method.GetGenericArguments();
_createMessageAccessor.Add(args.Length, method);
}
else if (method.Name == nameof(AccessorsFactory.CreateStreamAccessor))
{
CreateStreamAccessor = method;
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... r-with-2-p
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»