/// <summary> /// Overrides reflection result with <see cref="TypeOverride"/> for the specific type and optionally purge existing overrides. /// </summary> /// <param name="type">The type to be overridden.</param> /// <param name="overrideInfo">The override info of the type.</param> /// <param name="purgeExisting">If this value is true, the reflection engine will reflect the type again and apply the <paramref name="overrideInfo"/>, otherwise, <paramref name="overrideInfo"/> is merged into the existing reflection cache.</param> /// <remarks> /// <para>At this moment, the override only affects the registered type.</para> /// <para>If a class has its subclasses, the override will not be applied to its subclasses.</para> /// </remarks> /// <exception cref="ArgumentNullException">The parameter <paramref name="type"/> or <paramref name="overrideInfo"/> is null.</exception> /// <exception cref="MissingMemberException">No member is found for a <see cref="MemberOverride"/> in <paramref name="overrideInfo"/>.</exception> public void Override(Type type, TypeOverride overrideInfo, bool purgeExisting) { if (type == null) { throw new ArgumentNullException("type"); } if (overrideInfo == null) { throw new ArgumentNullException("overrideInfo"); } lock (_syncRoot) { var s = GetSerializationInfo(type); if (purgeExisting) { LoadSerializationInfo(s); } OverrideSerializationInfo(s, overrideInfo); if (overrideInfo._MemberOverrides == null || overrideInfo._MemberOverrides.Count == 0) { return; } // add properties ignored by _controller in GetProperties method foreach (var ov in overrideInfo._MemberOverrides) { //if (ov.Deserializable != true) { // continue; //} var p = s.FindProperties(ov.MemberName); if (p.Count == 0) { var m = s.Reflection.FindMemberCache(ov.MemberName); if (m == null) { throw new MissingMemberException(s.Reflection.TypeName, ov.MemberName); } var pi = new JsonMemberSetter(s, m, this); // TODO: load serialization control settings var ds = LoadMemberDeserializationSettings(pi, _controller); if (ds != null) { foreach (var item in ds) { AddSetter(s.Setters, item.Key, item.Value); } } } } foreach (var ov in overrideInfo._MemberOverrides) { var g = s.FindGetters(ov.MemberName); if (g == null) { throw new MissingMemberException(type.FullName, ov.MemberName); } OverrideGetter(g, ov); OverrideSetter(s.Setters, ov, g); } } }
private void OverrideSerializationInfo(SerializationInfo info, TypeOverride overrideInfo) { if (overrideInfo.OverrideAlias) { var a = overrideInfo.Alias; if (String.IsNullOrEmpty(a)) { _typeAliases.Remove(info.Reflection.Type); if (info.Alias != null) { _reverseTypeAliases.Remove(info.Alias); } } else { Type t; if (_reverseTypeAliases.TryGetValue(a, out t)) { if (t.Equals(info.Reflection.Type) == false) { throw new JsonSerializationException("Type alias (" + a + ") has been used by type " + t.AssemblyQualifiedName); } } else { if (info.Alias != null) { _reverseTypeAliases.Remove(info.Alias); } info.Alias = overrideInfo.Alias; _typeAliases[info.Reflection.Type] = info.Alias; _reverseTypeAliases[a] = info.Reflection.Type; } } } if (overrideInfo.OverrideInterceptor) { info.Interceptor = overrideInfo.Interceptor; } if (overrideInfo.OverrideConverter) { info.Converter = overrideInfo.Converter; } if (overrideInfo.OverrideContainerName) { info.CollectionName = overrideInfo.CollectionContainer; info.DeserializeMethod = overrideInfo.CollectionContainer == null ? JsonDeserializer.GetReadJsonMethod(info.Reflection.Type) : new CompoundDeserializer(info.CollectionName, info.Reflection.DeserializeMethod).Deserialize; } if (overrideInfo.Deserializable.HasValue) { info.AlwaysDeserializable = overrideInfo.Deserializable == true; } }
/// <summary> /// Overrides reflection result with <see cref="TypeOverride"/> for the <typeparamref name="T"/> type. /// </summary> /// <typeparam name="T">The type to be overridden.</typeparam> /// <param name="overrideInfo">The override info of the type.</param> /// <param name="purgeExisting">If this value is true, the reflection engine will reflect the type again and apply the <paramref name="overrideInfo"/>, otherwise, <paramref name="overrideInfo"/> is merged into the existing reflection cache.</param> /// <seealso cref="Override(Type,TypeOverride,bool)"/> public void Override <T>(TypeOverride overrideInfo, bool purgeExisting) { Override(typeof(T), overrideInfo, purgeExisting); }
/// <summary> /// Overrides reflection result with <see cref="TypeOverride"/> for the <typeparamref name="T"/> type. If the type is already overridden, either automatically or manually, the <paramref name="overrideInfo"/> will merged into the existing reflected info. /// </summary> /// <typeparam name="T">The type to be overridden.</typeparam> /// <param name="overrideInfo">The override info of the type.</param> /// <seealso cref="Override(Type,TypeOverride,bool)"/> public void Override <T>(TypeOverride overrideInfo) { Override(typeof(T), overrideInfo, false); }