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);
            }
예제 #3
0
        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);
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        /// <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);
                }
            }
        }
예제 #6
0
 /// <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;
예제 #7
0
 protected override bool TryBind <TService, TRequest, TResponse>(ServiceBindContext bindContext, Method <TRequest, TResponse> method, MethodStub <TService> stub)
 {
     Methods.Add(method.Name);
     return(true);
 }