Exemplo n.º 1
0
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                            JsonSerializer serializer)
            {
                if (reader.TokenType == JsonToken.Null)
                {
                    return(null);
                }
                if (objectType.IsAbstract)
                {
                    var  jo = JObject.Load(reader);
                    Type boType;
                    if (serializer.TypeNameHandling.HasFlag(TypeNameHandling.Objects) &&
                        jo.TryGetValue("$type", out var typeToken))
                    {
                        boType = BusinessObjectSerializationBinder.BusinessObjectAndCOMTypes.SingleOrDefault(t =>
                                                                                                             typeToken.Value <string>().ToUpper().StartsWith(t.FullName.ToUpper()));
                    }
                    else if (!jo.ContainsKey("boTyp"))
                    {
                        throw new ArgumentException(
                                  "If deserializing into an abstract BusinessObject the key \"boTyp\" has to be set. But it wasn't.");
                    }
                    else
                    {
#pragma warning disable CS0618                                                 // Type or member is obsolete
                        boType = BoMapper.GetTypeForBoName(jo["boTyp"]
                                                           .Value <string>()); // ToDo: catch exception if boTyp is not set and throw exception with descriptive error message
#pragma warning restore CS0618                                                 // Type or member is obsolete
                    }

                    if (boType == null)
                    {
                        foreach (var assembley in AppDomain.CurrentDomain.GetAssemblies())
                        {
                            try
                            {
                                boType = assembley.GetTypes().FirstOrDefault(x => string.Equals(x.Name,
                                                                                                jo["boTyp"].Value <string>(), StringComparison.CurrentCultureIgnoreCase));
                            }
                            catch (ReflectionTypeLoadException)
                            {
                                continue;
                            }

                            if (boType != null)
                            {
                                break;
                            }
                        }

                        if (boType == null)
                        {
                            throw new NotImplementedException(
                                      $"The type '{jo["boTyp"].Value<string>()}' does not exist in the BO4E standard.");
                        }
                    }

                    var deserializationMethod = serializer.GetType() // https://stackoverflow.com/a/5218492/10009545
                                                .GetMethods()
                                                .Where(m => m.Name == nameof(serializer.Deserialize))
                                                .Select(m => new
                    {
                        Method = m,
                        Params = m.GetParameters(),
                        Args   = m.GetGenericArguments()
                    })
                                                .Where(x => x.Params.Length == 1 &&
                                                       x.Args.Length == 1)
                                                .Select(x => x.Method)
                                                .First()
                                                .GetGenericMethodDefinition()
                                                .MakeGenericMethod(boType);
                    try
                    {
                        return(deserializationMethod.Invoke(serializer, new object[] { jo.CreateReader() }));
                    }
                    catch (TargetInvocationException tie) when(tie.InnerException != null)
                    {
                        throw tie.InnerException; // to hide the reflection to the outside.
                    }
                }

                serializer.ContractResolver.ResolveContract(objectType).Converter = null;
                return(serializer.Deserialize(JObject.Load(reader).CreateReader(), objectType));
            }