Exemple #1
0
        private Type ResolveType(TypeSerializationInfo info)
        {
            if (!_typeNameShortener.TryExpand(info.Name, out Type type))
            {
                if (_assemblyNameShortener.TryExpand(info.Assembly?.Name, out Assembly assembly))
                {
                    info.Assembly = assembly.ToAssemblySerializationInfo();
                }

                var infoForResolving = info.GenericArgs?.Length > 0
                    ? new TypeSerializationInfo
                {
                    Name     = info.Name,
                    Assembly = info.Assembly
                }
                    : info;
                type = _typeResolver.Resolve(infoForResolving);
            }

            if (type.IsGenericTypeDefinition())
            {
                var genericArguments = new Type[info.GenericArgs.Length];
                for (var i = 0; i < genericArguments.Length; i++)
                {
                    var genericArgument = ResolveType(info.GenericArgs[i]);
                    genericArguments[i] = genericArgument;
                }
                type = type.MakeGenericType(genericArguments);
            }

            return(type);
        }
        public Type Resolve(TypeSerializationInfo info)
        {
            if (string.IsNullOrEmpty(info.Name))
            {
                throw new ArgumentException($"Empty {nameof(TypeSerializationInfo)}.{nameof(TypeSerializationInfo.Name)}");
            }

#warning Cache results

            Type type;
            if (info.Assembly != null)
            {
                var assembly = _assemblyResolver.Resolve(info.Assembly);
                type = assembly.GetType(info.Name, throwOnError: true, ignoreCase: false);
            }
            else
            {
                type = Type.GetType(info.Name, throwOnError: true, ignoreCase: false);
            }

            if (info.GenericArgs?.Length > 0)
            {
                if (!type.IsGenericTypeDefinition())
                {
                    throw new InvalidOperationException(
                              $"The type '{type}' is not a generic type definition.");
                }

                var genericArguments = new Type[info.GenericArgs.Length];
                for (var i = 0; i < genericArguments.Length; i++)
                {
                    genericArguments[i] = Resolve(info.GenericArgs[i]);
                }

                type = type.MakeGenericType(genericArguments);
            }

            return(type);
        }
        internal static TypeSerializationInfo ParseInternal(string typeFullName, ref int startIndex)
        {
            var result = new TypeSerializationInfo();

            // Skip whitespace
            while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
            {
                startIndex++;
            }

            // Parse Name
            var nameEndIndex = startIndex;

            for ( ; nameEndIndex < typeFullName.Length; nameEndIndex++)
            {
                if (typeFullName[nameEndIndex] == '[' ||
                    typeFullName[nameEndIndex] == ']' ||
                    typeFullName[nameEndIndex] == ',' ||
                    typeFullName[nameEndIndex] == ' ')
                {
                    break;
                }
            }
            result.Name = typeFullName.Substring(startIndex, nameEndIndex - startIndex);
            startIndex  = nameEndIndex;

            // Skip whitespace
            while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
            {
                startIndex++;
            }

            // Generic arguments
            if (startIndex < typeFullName.Length && typeFullName[startIndex] == '[')
            {
                startIndex++;

                // Skip whitespace
                while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                {
                    startIndex++;
                }

                var genericArgs = new List <TypeSerializationInfo>(capacity: 2);

                var hasMoreGenericArgs = true;

                while (hasMoreGenericArgs)
                {
                    bool isTypeNameQuoted = false;
                    if (typeFullName[startIndex] == '[')
                    {
                        isTypeNameQuoted = true;
                        startIndex++;
                    }

                    // Skip whitespace
                    while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                    {
                        startIndex++;
                    }

                    var genericArg = ParseInternal(typeFullName, ref startIndex);
                    genericArgs.Add(genericArg);

                    // Skip whitespace
                    while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                    {
                        startIndex++;
                    }

                    if (isTypeNameQuoted)
                    {
                        if (typeFullName[startIndex] != ']')
                        {
                            throw new InvalidOperationException("Type full name format error");
                        }
                        startIndex++;

                        // Skip whitespace
                        while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                        {
                            startIndex++;
                        }
                    }

                    if (typeFullName[startIndex] == ']')
                    {
                        hasMoreGenericArgs = false;

                        startIndex++;

                        // Skip whitespace
                        while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                        {
                            startIndex++;
                        }
                    }
                    else if (typeFullName[startIndex] == ',')
                    {
                        startIndex++;

                        // Skip whitespace
                        while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                        {
                            startIndex++;
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Type full name format error");
                    }
                }

                result.GenericArgs = genericArgs.ToArray();
            }

            // Assembly name
            if (startIndex < typeFullName.Length && typeFullName[startIndex] == ',')
            {
                startIndex++;

                // Skip whitespace
                while (startIndex < typeFullName.Length && typeFullName[startIndex] == ' ')
                {
                    startIndex++;
                }

                var endIndex = typeFullName.IndexOf(']', startIndex);
                if (endIndex < 0)
                {
                    endIndex = typeFullName.Length;
                }

                result.Assembly = AssemblySerializationInfo.ParseInternal(typeFullName, startIndex, endIndex);
                startIndex      = endIndex;
            }

            return(result);
        }