public virtual void ApplyDefaultBehaviour(MetaType metaType) { var type = metaType.Type; Type baseType = metaType.GetBaseType(); if (baseType != null && CanAutoAddType(baseType) && MetaType.CanHaveSubType(baseType)) { Model.FindOrAddAuto(baseType, true, false, false); } try { AttributeFamily family; TypeState mapped; { AttributeMap[] typeAttribs = AttributeMap.Create(Model, type, false); family = GetContractFamily(type, typeAttribs); mapped = TypeMapper.Map( new TypeArgsValue(type, typeAttribs, AcceptableAttributes, Model) { Family = family, ImplicitFallbackMode = ImplicitFallbackMode, }); foreach (var candidate in mapped.DerivedTypes) { if (metaType.IsValidSubType(candidate.Type)) { metaType.AddSubType(candidate.Tag, candidate.Type); } } metaType.ReplaceClientSettings(mapped.SettingsValue); } var partialMembers = mapped.PartialMembers; int dataMemberOffset = mapped.DataMemberOffset; int implicitFirstTag = mapped.ImplicitFirstTag; bool inferTagByName = mapped.InferTagByName; ImplicitFieldsMode implicitMode = mapped.ImplicitFields; family = mapped.Input.Family; MethodInfo[] callbacks = null; var members = new List <MappedMember>(); bool isEnum = Helpers.IsEnum(type); #if WINRT System.Collections.Generic.IEnumerable <MemberInfo> foundList; if (isEnum) { foundList = type.GetRuntimeFields().Where(x => x.IsStatic && x.IsPublic); } else { System.Collections.Generic.List <MemberInfo> list = new System.Collections.Generic.List <MemberInfo>(); foreach (PropertyInfo prop in type.GetRuntimeProperties()) { MethodInfo getter = Helpers.GetGetMethod(prop, false, false); if (getter != null && !getter.IsStatic) { list.Add(prop); } } foreach (FieldInfo fld in type.GetRuntimeFields()) { if (fld.IsPublic && !fld.IsStatic) { list.Add(fld); } } foreach (MethodInfo mthd in type.GetRuntimeMethods()) { if (mthd.IsPublic && !mthd.IsStatic) { list.Add(mthd); } } foundList = list; } #else MemberInfo[] foundList = type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (isEnum) { foundList = foundList.Where(x => x is FieldInfo).ToArray(); } #endif foreach (MemberInfo member in foundList) { if (member.DeclaringType != type) { continue; } var map = AttributeMap.Create(Model, member, true); { var args = new MemberArgsValue(member, map, AcceptableAttributes, Model) { DataMemberOffset = dataMemberOffset, Family = family, InferTagByName = inferTagByName, PartialMembers = partialMembers, IsEnumValueMember = isEnum }; PropertyInfo property; FieldInfo field; if ((property = member as PropertyInfo) != null) { bool isPublic = Helpers.GetGetMethod(property, false, false) != null; bool canBeMapped = isPublic || Helpers.GetGetMethod(property, true, true) != null; if (canBeMapped && (!mapped.ImplicitOnlyWriteable || Helpers.CheckIfPropertyWritable ( Model, property, implicitMode == ImplicitFieldsMode.AllProperties || implicitMode == ImplicitFieldsMode.AllFieldsAndProperties, false))) { switch (implicitMode) { case ImplicitFieldsMode.AllProperties: args.IsForced = true; break; case ImplicitFieldsMode.PublicProperties: if (isPublic) { args.IsForced = true; } break; case ImplicitFieldsMode.PublicFieldsAndProperties: if (isPublic) { args.IsForced = true; } break; case ImplicitFieldsMode.AllFieldsAndProperties: args.IsForced = true; break; } } var r = ApplyDefaultBehaviour_AddMembers(args); if (r != null) { if (!canBeMapped) { throw new MemberAccessException("Property " + property + " should be readable to be mapped."); } members.Add(r); } } else if ((field = member as FieldInfo) != null) { bool isPublic = field.IsPublic; if (!args.IsEnumValueMember) { switch (implicitMode) { case ImplicitFieldsMode.AllFields: args.IsForced = true; break; case ImplicitFieldsMode.PublicFields: if (isPublic) { args.IsForced = true; } break; case ImplicitFieldsMode.PublicFieldsAndProperties: if (isPublic) { args.IsForced = true; } break; case ImplicitFieldsMode.AllFieldsAndProperties: args.IsForced = true; break; } } var r = ApplyDefaultBehaviour_AddMembers(args); if (r != null) { members.Add(r); } } } MethodInfo method; if ((method = member as MethodInfo) != null) { AttributeMap[] memberAttribs = AttributeMap.Create(Model, method, false); if (memberAttribs != null && memberAttribs.Length > 0) { const int max = 11; if (CanUse(AttributeType.ProtoBuf)) { CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0, max); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1, max); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2, max); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3, max); } CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4, max); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5, max); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6, max); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7, max); if (CanUse(AttributeType.Aqla)) { CheckForCallback(method, memberAttribs, "AqlaSerializer.BeforeSerializationCallbackAttribute", ref callbacks, 8, max); CheckForCallback(method, memberAttribs, "AqlaSerializer.AfterSerializationCallbackAttribute", ref callbacks, 9, max); CheckForCallback(method, memberAttribs, "AqlaSerializer.BeforeDeserializationCallbackAttribute", ref callbacks, 10, max); CheckForCallback(method, memberAttribs, "AqlaSerializer.AfterDeserializationCallbackAttribute", ref callbacks, 11, max); } } } } if (inferTagByName || implicitMode != ImplicitFieldsMode.None) { members.Sort(); foreach (var member in members) { if (!member.MappingState.TagIsPinned) // if ProtoMember etc sets a tag, we'll trust it { member.Tag = -1; } } } foreach (var member in members.OrderBy(m => m.MappingState.TagIsPinned ? 0 : 1)) { ApplyDefaultBehaviour(metaType, member, (inferTagByName || implicitMode != ImplicitFieldsMode.None) ? (int?)implicitFirstTag : null); } if (callbacks != null) { metaType.SetCallbacks(Coalesce(callbacks, 0, 4, 8), Coalesce(callbacks, 1, 5, 9), Coalesce(callbacks, 2, 6, 10), Coalesce(callbacks, 3, 7, 11)); } if (!DisableAutoAddingMemberTypes) { foreach (var member in members) { if (!member.MappingState.Input.IsEnumValueMember) { Type memberType = Helpers.GetMemberType(member.Member); memberType = Helpers.GetNullableUnderlyingType(memberType) ?? memberType; if (memberType.IsArray) { memberType = memberType.GetElementType(); } memberType = TypeModel.GetListItemType(Model, memberType) ?? memberType; if (memberType == null) { continue; } if (CanAutoAddType(memberType)) { Model.FindOrAddAuto(memberType, true, false, false); } } } } if (UseLegacyTupleFields) { foreach (ValueMember vm in metaType.GetTupleFields()) { vm.SetSettings(x => x.V.DefaultsMode = MemberDefaultsMode.LegacyTuple); } } } finally { if (baseType != null && GetContractFamily(baseType) != AttributeFamily.None) { if (Model.FindWithoutAdd(baseType) != null) { MetaType baseMeta = Model[baseType]; // we can't add to frozen base type // but this is not always an error // e.g. dynamic member of base type doesn't need registered subtype if (!baseMeta.IsFrozen && !DisableAutoRegisteringSubtypes && !baseMeta.IsList && baseMeta.IsValidSubType(type) && CanAutoAddType(baseType)) { baseMeta.AddSubType(baseMeta.GetNextFreeFieldNumber(AutoRegisteringSubtypesFirstTag), type); } } } } }