protected override bool TryBind <TService, TRequest, TResponse>(ServiceBindContext bindContext, Method <TRequest, TResponse> method, MethodStub <TService> stub) where TService : class where TRequest : class where TResponse : class { var metadata = bindContext.GetMetadata(stub.Method); var context = (ServiceMethodProviderContext <TService>)bindContext.State; switch (method.Type) { case MethodType.Unary: context.AddUnaryMethod(method, metadata, stub.CreateDelegate <UnaryServerMethod <TService, TRequest, TResponse> >()); break; case MethodType.ClientStreaming: context.AddClientStreamingMethod(method, metadata, stub.CreateDelegate <ClientStreamingServerMethod <TService, TRequest, TResponse> >()); break; case MethodType.ServerStreaming: context.AddServerStreamingMethod(method, metadata, stub.CreateDelegate <ServerStreamingServerMethod <TService, TRequest, TResponse> >()); break; case MethodType.DuplexStreaming: context.AddDuplexStreamingMethod(method, metadata, stub.CreateDelegate <DuplexStreamingServerMethod <TService, TRequest, TResponse> >()); break; default: return(false); } return(true); }
protected override bool TryBind <TService, TRequest, TResponse>(ServiceBindContext bindContext, Method <TRequest, TResponse> method, MethodStub <TService> stub) where TService : class where TRequest : class where TResponse : class { var builder = (ServerServiceDefinition.Builder)bindContext.State; switch (method.Type) { case MethodType.Unary: builder.AddMethod(method, stub.CreateDelegate <UnaryServerMethod <TRequest, TResponse> >()); break; case MethodType.ClientStreaming: builder.AddMethod(method, stub.CreateDelegate <ClientStreamingServerMethod <TRequest, TResponse> >()); break; case MethodType.ServerStreaming: builder.AddMethod(method, stub.CreateDelegate <ServerStreamingServerMethod <TRequest, TResponse> >()); break; case MethodType.DuplexStreaming: builder.AddMethod(method, stub.CreateDelegate <DuplexStreamingServerMethod <TRequest, TResponse> >()); break; default: return(false); } _log?.WriteLine($"{method.ServiceName} / {method.Name} ({method.Type}) bound to {stub.Method.DeclaringType.Name}.{stub.Method.Name}"); return(true); }
public void AttributesDetectedWherever(string methodName, string expected) { var ctx = new ServiceBindContext(typeof(ISomeService), typeof(SomeServer), "n/a"); var method = typeof(ISomeService).GetMethod(methodName) !; var actual = string.Join(",", ctx.GetMetadata(method).OfType <SomethingAttribute>().Select(x => x.Value)); Assert.Equal(expected, actual); }
private bool AddMethod <TService, TRequest, TResponse>( string serviceName, string operationName, MethodInfo method, MethodType methodType, ServiceBindContext bindContext, Func <MethodInfo, Expression[], Expression>?invoker, MarshallerCache marshallerCache, ConstantExpression?service) where TService : class where TRequest : class where TResponse : class { var grpcMethod = new Method <TRequest, TResponse>(methodType, serviceName, operationName, marshallerCache.GetMarshaller <TRequest>(), marshallerCache.GetMarshaller <TResponse>()); var stub = new MethodStub <TService>(invoker, method, service); try { return(TryBind <TService, TRequest, TResponse>(bindContext, grpcMethod, stub)); } catch (Exception ex) { OnError(ex.Message); return(false); } }
/// <summary> /// Initiate a bind operation, causing all service methods to be crawled for the provided type /// </summary> public int Bind(object state, Type serviceType, BinderConfiguration?binderConfiguration = null, object?service = null) { int totalCount = 0; object?[]? argsBuffer = null; Type[] typesBuffer = Array.Empty <Type>(); string? serviceName; if (binderConfiguration == null) { binderConfiguration = BinderConfiguration.Default; } var serviceContracts = typeof(IGrpcService).IsAssignableFrom(serviceType) ? new HashSet <Type> { serviceType } : ContractOperation.ExpandInterfaces(serviceType); foreach (var serviceContract in serviceContracts) { if (!binderConfiguration.Binder.IsServiceContract(serviceContract, out serviceName)) { continue; } int svcOpCount = 0; var bindCtx = new ServiceBindContext(serviceContract, serviceType, state); foreach (var op in ContractOperation.FindOperations(binderConfiguration, serviceContract, this)) { if (ServerInvokerLookup.TryGetValue(op.MethodType, op.Context, op.Result, op.Void, out var invoker) && AddMethod(op.From, op.To, op.Name, op.Method, op.MethodType, invoker, bindCtx)) { // yay! totalCount++; svcOpCount++; } } OnServiceBound(state, serviceName !, serviceType, serviceContract, svcOpCount); } return(totalCount); bool AddMethod(Type @in, Type @out, string on, MethodInfo m, MethodType t, Func <MethodInfo, ParameterExpression[], Expression>?invoker, ServiceBindContext bindContext) { try { if (typesBuffer.Length == 0) { typesBuffer = new Type[] { serviceType, typeof(void), typeof(void) }; } typesBuffer[1] = @in; typesBuffer[2] = @out; if (argsBuffer == null) { argsBuffer = new object?[] { null, null, null, null, null, null, binderConfiguration !.MarshallerCache, service == null ? null : Expression.Constant(service, serviceType) }; } argsBuffer[0] = serviceName; argsBuffer[1] = on; argsBuffer[2] = m; argsBuffer[3] = t; argsBuffer[4] = bindContext; argsBuffer[5] = invoker; return((bool)s_addMethod.MakeGenericMethod(typesBuffer).Invoke(this, argsBuffer) !); } catch (Exception fail) { if (fail is TargetInvocationException tie) { fail = tie.InnerException !; } return(false); } } }
/// <summary> /// The implementing binder should bind the method to the bind-state /// </summary> protected abstract bool TryBind <TService, TRequest, TResponse>(ServiceBindContext bindContext, Method <TRequest, TResponse> method, MethodStub <TService> stub) where TService : class where TRequest : class where TResponse : class;
protected override bool TryBind <TService, TRequest, TResponse>(ServiceBindContext bindContext, Method <TRequest, TResponse> method, MethodStub <TService> stub) { Methods.Add(method.Name); return(true); }