Beispiel #1
0
        internal void AddGenericEventHandler <TEventArgs>(RpcStub <TService> serviceStub, RpcEventInfo eventInfo, TMethodBinder binder) where TEventArgs : class
        {
            if (eventInfo.Event.EventHandlerType == null || eventInfo.Event.AddMethod == null || eventInfo.Event.RemoveMethod == null)
            {
                throw new NotSupportedException($"Service event handler for '{eventInfo.DeclaringMember.Name}' must be full defined.");
            }

            var serviceParameter  = Expression.Parameter(typeof(TService));
            var delegateParameter = Expression.Parameter(typeof(Delegate));

            var castDelegateExpression = Expression.Convert(delegateParameter, eventInfo.Event.EventHandlerType);

            var addHandlerExpression = Expression.Call(serviceParameter, eventInfo.Event.AddMethod, castDelegateExpression);
            var addHandlerAction     = Expression.Lambda <Action <TService, Delegate> >(addHandlerExpression, serviceParameter, delegateParameter).Compile();

            var removeHandlerExpression = Expression.Call(serviceParameter, eventInfo.Event.RemoveMethod, castDelegateExpression);
            var removeHandlerAction     = Expression.Lambda <Action <TService, Delegate> >(removeHandlerExpression, serviceParameter, delegateParameter).Compile();

            ValueTask LocalBeginEventProducer(RpcObjectRequest request, IServiceProvider?serviceProvider, IRpcAsyncStreamWriter <TEventArgs> responseStream, IRpcContext context)
            {
                var eventProducer = new GenericEventHandlerProducer <TEventArgs>(responseStream, addHandlerAction, removeHandlerAction, context.CancellationToken);

                return(serviceStub.BeginEventProducer(request, serviceProvider, eventProducer));
            }

            this.AddEventHandlerDefinition <TEventArgs>(eventInfo, LocalBeginEventProducer, serviceStub, binder);
        }
Beispiel #2
0
 protected abstract void AddGenericVoidBlockingMethodCore <TRequest>(
     Action <TService, TRequest, CancellationToken> serviceCaller,
     RpcServerFaultHandler faultHandler,
     RpcStub <TService> serviceStub,
     RpcOperationInfo operationInfo,
     TMethodBinder binder)
     where TRequest : class, IObjectRequest;
Beispiel #3
0
 protected abstract void AddGenericBlockingMethodCore <TRequest, TReturn, TResponseReturn>(
     Func <TService, TRequest, CancellationToken, TReturn> serviceCaller,
     Func <TReturn, TResponseReturn>?responseConverter,
     RpcServerFaultHandler faultHandler,
     RpcStub <TService> serviceStub,
     RpcOperationInfo operationInfo,
     TMethodBinder binder)
     where TRequest : class, IObjectRequest;
Beispiel #4
0
            where TResponseReturn : class;  // Needs to be class due to gRPC restriction

        protected abstract void AddCallbackMethodCore <TRequest, TReturn, TResponseReturn>(
            Func <TService, TRequest, Action <TReturn>, CancellationToken, Task> serviceCaller,
            Func <TReturn, TResponseReturn>?responseConverter,
            RpcServerFaultHandler faultHandler,
            RpcStub <TService> serviceStub,
            RpcOperationInfo operationInfo,
            TMethodBinder binder)
            where TRequest : class, IObjectRequest
            where TResponseReturn : class;  // Needs to be class due to gRPC constraint
Beispiel #5
0
 protected abstract void AddServerStreamingMethodCore <TRequest, TReturn, TResponseReturn>(
     Func <TService, TRequest, CancellationToken, IAsyncEnumerable <TReturn> > serviceCaller,
     Func <TReturn, TResponseReturn>?responseConverter,
     RpcServerFaultHandler faultHandler,
     RpcStub <TService> serviceStub,
     RpcOperationInfo operationInfo,
     TMethodBinder binder)
     where TRequest : class, IObjectRequest
     where TResponseReturn : class;  // Needs to be class due to gRPC restriction
Beispiel #6
0
        internal void AddEventHandler(RpcStub <TService> serviceStub, RpcEventInfo eventInfo, TMethodBinder binder)
        {
            if (typeof(EventHandler).Equals(eventInfo.Event.EventHandlerType))
            {
                this.AddPlainEventHandler(serviceStub, eventInfo, binder);
                return;
            }

            // TODO: Cache.
            var addEventHandlerDelegate = (Action <RpcStub <TService>, RpcEventInfo, TMethodBinder>)
                                          GetBuilderMethod(nameof(this.AddGenericEventHandler))
                                          .MakeGenericMethod(eventInfo.EventArgsType)
                                          .CreateDelegate(typeof(Action <RpcStub <TService>, RpcEventInfo, TMethodBinder>), this);

            addEventHandlerDelegate(serviceStub, eventInfo, binder);
        }
Beispiel #7
0
        /// <summary>
        /// Generates the RPC method definitions and stub handlers and adds them to the provided methodBinder.
        /// </summary>
        /// <returns></returns>
        public RpcStub <TService> GenerateOperationHandlers(IRpcServerCore server, TMethodBinder methodBinder)
        {
            this.serviceStub = this.CreateServiceStub(server);

            foreach (var memberInfo in RpcBuilderUtil.EnumOperationHandlers(this.ServiceInfo, true))
            {
                if (memberInfo is RpcEventInfo eventInfo)
                {
                    this.AddEventHandler(this.serviceStub, eventInfo, methodBinder);
                }
                else if (memberInfo is RpcOperationInfo opInfo)
                {
                    switch (opInfo.MethodType)
                    {
                    case RpcMethodType.Unary:
                        this.CheckMethod(opInfo);
                        this.AddUnaryMethod(this.serviceStub, opInfo, methodBinder);
                        break;

                    case RpcMethodType.ServerStreaming:
                        this.CheckMethod(opInfo);
                        if (opInfo.CallbackParameterIndex == null)
                        {
                            // No callback. Implement using IAsyncEnumerable
                            this.AddServerStreamingMethod(this.serviceStub, opInfo, methodBinder);
                        }
                        else
                        {
                            // Implement using callback
                            this.AddCallbackMethod(this.serviceStub, opInfo, methodBinder);
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return(this.serviceStub);
        }
Beispiel #8
0
        protected void AddGenericBlockingMethod <TRequest, TReturn, TResponseReturn>(RpcStub <TService> serviceStub, RpcOperationInfo opInfo, TMethodBinder binder)
            where TRequest : class, IObjectRequest
        {
            if (opInfo is null)
            {
                throw new ArgumentNullException(nameof(opInfo));
            }

            Func <TReturn, TResponseReturn>?responseCreator = GetResponseCreator <TReturn, TResponseReturn>(opInfo);
            RpcServerFaultHandler           faultHandler    = this.CreateFaultHandler(opInfo);

            if (opInfo.IsAsync)
            {
                var serviceCaller = GenerateUnaryMethodHandler <TRequest, TReturn>(opInfo);
                this.AddGenericAsyncMethodCore(serviceCaller, responseCreator, faultHandler, serviceStub, opInfo, binder);
            }
            else
            {
                var serviceCaller = GenerateBlockingUnaryMethodHandler <TRequest, TReturn>(opInfo);
                this.AddGenericBlockingMethodCore(serviceCaller, responseCreator, faultHandler, serviceStub, opInfo, binder);
            }
        }
Beispiel #9
0
        protected void AddGenericServerStreamingMethod <TRequest, TReturn, TResponseReturn>(RpcStub <TService> serviceStub, RpcOperationInfo opInfo, TMethodBinder binder)
            where TRequest : class, IObjectRequest
            where TResponseReturn : class  // Needs to be class due to gRPC constraint
        {
            if (opInfo is null)
            {
                throw new ArgumentNullException(nameof(opInfo));
            }

            Func <TReturn, TResponseReturn>?responseCreator = GetResponseCreator <TReturn, TResponseReturn>(opInfo);
            RpcServerFaultHandler           faultHandler    = this.CreateFaultHandler(opInfo);

            var serviceCaller = GenerateServerStreamingMethodHandler <TRequest, TReturn>(opInfo);

            this.AddServerStreamingMethodCore(serviceCaller, responseCreator, faultHandler, serviceStub, opInfo, binder);
        }
Beispiel #10
0
 protected abstract void AddEventHandlerDefinition <TEventArgs>(
     RpcEventInfo eventInfo,
     Func <RpcObjectRequest, IServiceProvider?, IRpcAsyncStreamWriter <TEventArgs>, IRpcContext, ValueTask> beginEventProducer,
     RpcStub <TService> serviceStub,
     TMethodBinder binder)
     where TEventArgs : class;