Esempio n. 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GenericMessage"/> class.
        /// </summary>
        /// <param name="requestId">The request id.</param>
        /// <param name="invokeMethodInfo">The invoke method info.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="responseExptected">if set to <c>true</c> [response exptected].</param>
        public GenericMessage(long requestId, IInvokeMethodInfo invokeMethodInfo, object[] parameters, bool responseExptected)
        {
            this.Type      = responseExptected ? MessageType.MethodInvokeRequest : MessageType.AsyncMethodInvokeRequest;
            this.RequestId = requestId;
            this.Target    = TypeService.GetSourceCodeTypeName(invokeMethodInfo.InterfaceMethod.DeclaringType);

            this.Name    = invokeMethodInfo.QualifiedMethodName;
            this.Payload = parameters;
        }
Esempio n. 2
0
        private Type UnknownTypeResolver(SerializationContext context)
        {
            if (context.InterfaceType != null)
            {
                return(containerHost.GetInterfaceImplementationType(context.InterfaceType.FullName));
            }
            else if (context.ParentObject is GenericMessage &&
                     context.Key == GenericMessagePayloadPropertyName)
            {
                GenericMessage message = (GenericMessage)context.ParentObject;

                // check out of order json keys -> load manually
                if (message.Type == MessageType.Undefined)
                {
                    message.Type = (MessageType)short.Parse(GetJsonSimpleStringValue(context.JsonString, "Type"));
                }
                if (message.Type == MessageType.Exception)
                {
                    if (context.IsDeserialize)
                    {
                        // check if payload contains complex type (ExceptionWrapper)
                        // this check must be done because of backwards compatibility
                        int nextObjectOrValueIndex = context.ValueStartIndex + context.Key.Length + 3;
                        if (nextObjectOrValueIndex < context.JsonString.Length && context.JsonString[nextObjectOrValueIndex] == Structure.CharLeftBrace)
                        {
                            return(typeof(ExceptionWrapper));
                        }
                        else
                        {
                            return(typeof(string));
                        }
                    }
                    else
                    {
                        // always serialize wrapper object
                        return(typeof(ExceptionWrapper));
                    }
                }

                if (context.ExternalContext is IInvokeMethodInfo)
                {
                    // serialize context
                    IInvokeMethodInfo invokeInfo = (IInvokeMethodInfo)context.ExternalContext;

                    switch (message.Type)
                    {
                    case MessageType.MethodInvokeRequest:
                    case MessageType.AsyncMethodInvokeRequest:
                        if (context.ArrayIndex.HasValue)
                        {
                            var paramInfo = invokeInfo.ParameterInfos[context.ArrayIndex.Value];

                            if (paramInfo.IsOut)
                            {
                                // determine out parameter type
                                return(paramInfo.ParameterType.GetElementType());
                            }
                            else
                            {
                                return(paramInfo.ParameterType);
                            }
                        }
                        else
                        {
                            return(objectArrayType);
                        }

                    case MessageType.MethodInvokeResponse:


                        if (context.ArrayIndex.HasValue == false ||
                            context.ArrayIndex == 0)
                        {
                            return(TypeService.GetAsyncAwaitResultType(invokeInfo.InterfaceMethod.ReturnType));
                        }
                        else
                        {
                            // determine out parameter type
                            return(invokeInfo.OutParameters[context.ArrayIndex.Value - 1].ParameterType.GetElementType());
                        }
                    }
                }
                else if (context.ExternalContext is ISession)
                {
                    // deserialize context
                    ISession session = (ISession)context.ExternalContext;

                    switch (message.Type)
                    {
                    case MessageType.AsyncMethodInvokeRequest:
                    case MessageType.MethodInvokeRequest:

                        if (context.ArrayIndex.HasValue)
                        {
                            // check out of order json keys -> load manually
                            if (message.Name == null)
                            {
                                message.Name = GetJsonSimpleStringValue(context.JsonString, "Name");
                            }
                            if (message.Target == null)
                            {
                                message.Target = GetJsonSimpleStringValue(context.JsonString, "Target");
                            }


                            int cacheKey = message.Target.GetHashCode();
                            cacheKey = cacheKey * 23 + message.Name.GetHashCode();

                            ParameterInfo[] parameters;
                            if (!methodParameterCache.TryGetValue(cacheKey, out parameters))
                            {
                                Type interfaceServiceType;
                                if (TypeService.TryGetTypeByName(message.Target, out interfaceServiceType))
                                {
                                    MethodInfo mi = TypeService.GetMethodByName(interfaceServiceType, message.Name);
                                    if (mi == null)
                                    {
                                        throw new InvalidOperationException(string.Format("The method: \"{0}\" is not specified in the interface: \"{1}\"", message.Name, interfaceServiceType.AssemblyQualifiedName));
                                    }

                                    parameters = mi.GetParameters();

                                    methodParameterCache[cacheKey] = parameters;
                                }
                                else
                                {
                                    throw new TypeLoadException(string.Format("The interface \"{0}\" could not be found!", message.Target));
                                }
                            }

                            if (parameters.Length > context.ArrayIndex.Value)
                            {
                                return(parameters[context.ArrayIndex.Value].ParameterType);
                            }
                            else
                            {
                                // method does not support requested parameter index
                                // BL 02.05.2020: happened because of wrong escape json chars
                                throw new IndexOutOfRangeException($"Requested method parameter index {context.ArrayIndex.Value} not available in method {message.Target}; {message.Name}");
                            }
                        }
                        else
                        {
                            return(objectArrayType);
                        }

                    case MessageType.MethodInvokeResponse:

                        IInvokeState invokeState;
                        if (session.PendingRequests.TryGetValue(message.RequestId, out invokeState))
                        {
                            if (invokeState.OutParameterValues != null)
                            {
                                if (context.ArrayIndex.HasValue)
                                {
                                    if (context.ArrayIndex == 0)
                                    {
                                        return(invokeState.Method.ReturnType);
                                    }
                                    else
                                    {
                                        Type type = invokeState.MethodSource.OutParameters[context.ArrayIndex.Value - 1].ParameterType;
                                        type = type.GetElementType();
                                        return(type);
                                    }
                                }
                                else
                                {
                                    return(objectArrayType);
                                }
                            }
                            else if (context.ArrayIndex == 0 ||
                                     !context.ArrayIndex.HasValue)
                            {
                                // first arrar item contains method return type
                                // or payload only inlcudes return object
                                return(TypeService.GetAsyncAwaitResultType(invokeState.Method.ReturnType));
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Pending request ID: " + message.RequestId + " message not found!");
                        }
                        break;
                    }
                }
                else if ((message.Type == MessageType.MethodInvokeRequest ||
                          message.Type == MessageType.AsyncMethodInvokeRequest) &&
                         !context.ArrayIndex.HasValue)
                {
                    return(objectArrayType);
                }
            }

            return(null);
        }
Esempio n. 3
0
        public IValueItem DetermineSpecialInterfaceType(Type sourceType, Type defaultInterfaceType, ISerializeContext context)
        {
            // reverse lookup interfaces
            Type       resultType = null;
            IValueItem specialTarget;

            if (serializer.TryGetDifferentTargetType(sourceType, out specialTarget) &&
                specialTarget != null)
            {
                return(specialTarget);
            }

            // check contextual target type
            {
                if (sourceType.Equals(typeof(Communication.Common.GenericMessage)))
                {
                    resultType = typeof(IGenericMessage);
                }
                else if (context.ParentObject is IGenericMessage)
                {
                    IGenericMessage message = (IGenericMessage)context.ParentObject;

                    if (context.ExternalContext is IInvokeMethodInfo)
                    {
                        // serialize context
                        IInvokeMethodInfo invokeInfo = (IInvokeMethodInfo)context.ExternalContext;

                        switch (message.Type)
                        {
                        case MessageType.MethodInvokeRequest:
                        case MessageType.AsyncMethodInvokeRequest:
                            if (context.ArrayIndex.HasValue)
                            {
                                var paramInfo = invokeInfo.ParameterInfos[context.ArrayIndex.Value];

                                if (paramInfo.IsOut)
                                {
                                    // determine out parameter type
                                    resultType = paramInfo.ParameterType.GetElementType();
                                }
                                else
                                {
                                    resultType = paramInfo.ParameterType;
                                }
                            }
                            break;
                        //else
                        //{
                        //    return objectArrayType;
                        //}

                        case MessageType.MethodInvokeResponse:


                            if (context.ArrayIndex == 0 ||
                                !context.ArrayIndex.HasValue)
                            {
                                resultType = invokeInfo.InterfaceMethod.ReturnType;
                            }
                            else
                            {
                                // determine out parameter type
                                resultType = invokeInfo.OutParameters[context.ArrayIndex.Value - 1].ParameterType.GetElementType();
                            }
                            break;
                        }
                    }
                    else if (context.ExternalContext is ISession)
                    {
                        // deserialize context
                        ISession session = (ISession)context.ExternalContext;

                        switch (message.Type)
                        {
                        case MessageType.AsyncMethodInvokeRequest:
                        case MessageType.MethodInvokeRequest:

                            if (context.ArrayIndex.HasValue)
                            {
                                int cacheKey = message.Target.GetHashCode();
                                cacheKey = cacheKey * 23 + message.Name.GetHashCode();

                                ParameterInfo[] parameters;
                                if (!methodParameterCache.TryGetValue(cacheKey, out parameters))
                                {
                                    Type interfaceServiceType;
                                    if (TypeService.TryGetTypeByName(message.Target, out interfaceServiceType))
                                    {
                                        MethodInfo mi = TypeService.GetMethodByName(interfaceServiceType, message.Name);
                                        if (mi == null)
                                        {
                                            throw new InvalidOperationException(string.Format("The method: \"{0}\" is not specified in the interface: \"{1}\"", message.Name, interfaceServiceType.AssemblyQualifiedName));
                                        }

                                        parameters = mi.GetParameters();

                                        methodParameterCache[cacheKey] = parameters;
                                    }
                                    else
                                    {
                                        throw new TypeLoadException(string.Format("The interface \"{0}\" could not be found!", message.Target));
                                    }
                                }

                                resultType = parameters[context.ArrayIndex.Value].ParameterType;
                            }
                            else
                            {
                                resultType = objectArrayType;
                            }
                            break;

                        case MessageType.MethodInvokeResponse:

                            IInvokeState invokeState;
                            if (session.PendingRequests.TryGetValue(message.RequestId, out invokeState))
                            {
                                if (invokeState.OutParameterValues != null)
                                {
                                    if (context.ArrayIndex.HasValue)
                                    {
                                        if (context.ArrayIndex == 0)
                                        {
                                            resultType = invokeState.Method.ReturnType;
                                        }
                                        else
                                        {
                                            Type type = invokeState.MethodSource.OutParameters[context.ArrayIndex.Value - 1].ParameterType;
                                            type       = type.GetElementType();
                                            resultType = type;
                                        }
                                    }
                                    else
                                    {
                                        resultType = objectArrayType;
                                    }
                                }
                                else if (context.ArrayIndex == 0 ||
                                         !context.ArrayIndex.HasValue)
                                {
                                    // first arrar item contains method return type
                                    // or payload only inlcudes return object
                                    resultType = invokeState.Method.ReturnType;
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("Pending request ID: " + message.RequestId + " message not found!");
                            }
                            break;
                        }
                    }
                    else if ((message.Type == MessageType.MethodInvokeRequest ||
                              message.Type == MessageType.AsyncMethodInvokeRequest) &&
                             !context.ArrayIndex.HasValue)
                    {
                        resultType = objectArrayType;
                    }
                }
            }

            if (resultType != null)
            {
                return(serializer.RegisterDifferentTargetType(sourceType, defaultInterfaceType, resultType, context));
            }
            else
            {
                return(serializer.DetermineSpecialInterfaceType(sourceType, defaultInterfaceType, context));;
            }
        }