Beispiel #1
0
        /// <summary>
        /// Get async handler from cache or by reflection.
        /// </summary>
        /// <param name="methodAbi">The abi definition of the method.</param>
        /// <returns>An async handler that takes serialized parameters and returns a IMessage.</returns>
        private Func <byte[], Task <RetVal> > GetAsyncHandler(Method methodAbi)
        {
            if (_asyncHandlersCache.TryGetValue(methodAbi, out var handler))
            {
                return(handler);
            }

            var methodInfo = _smartContract.GetType().GetMethod(methodAbi.Name);

            _retTypes.TryGetValue(methodAbi.ReturnType, out var retType);

            if (!_asyncApplyHanders.TryGetValue(methodAbi.ReturnType, out var applyHandler))
            {
                if (methodInfo.ReturnType.GenericTypeArguments[0].IsPbMessageType())
                {
                    applyHandler = InvokeAsyncHandlers.ForPbMessageReturnType;
                    retType      = RetVal.Types.RetType.PbMessage;
                }
                else if (methodInfo.ReturnType.GenericTypeArguments[0].IsUserType())
                {
                    applyHandler = InvokeAsyncHandlers.ForUserTypeReturnType;
                    retType      = RetVal.Types.RetType.UserType;
                }
            }

            if (applyHandler == null)
            {
                return(null);
            }

            var contract = _smartContract;

            handler = async(paramsBytes) =>
            {
                var parameters = ParamsPacker.Unpack(paramsBytes,
                                                     methodInfo.GetParameters().Select(y => y.ParameterType).ToArray());
                var msg = await applyHandler(methodInfo, contract, parameters);

                return(new RetVal
                {
                    Type = retType,
                    Data = msg.ToByteString()
                });
            };
            _asyncHandlersCache[methodAbi] = handler;
            return(handler);
        }