- Timestamp:
- 03/15/10 12:02:00 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable
- Files:
-
- 3 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableClassAttribute.cs
r3025 r3029 4 4 using System.Linq; 5 5 6 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable { 7 8 9 /// <summary> 10 /// Specifies which memebrs are selected for serialization by the StorableSerializer 11 /// </summary> 12 public enum StorableClassType { 13 14 /// <summary> 15 /// Serialize only fields and properties that have been marked 16 /// with the [Storable] attribute. This is the default value. 17 /// </summary> 18 MarkedOnly, 19 20 /// <summary> 21 /// Serialize all fields but ignore the 22 /// [Storable] attribute on properties. 23 /// </summary> 24 [Obsolete("not implemented yet")] 25 AllFields, 26 27 /// <summary> 28 /// Serialize all properties but ignore the 29 /// [Storable] attirbute on fields. 30 /// </summary> 31 [Obsolete("not implemented yet")] 32 AllProperties, 33 34 /// <summary> 35 /// Serialize all fields and all properties 36 /// but ignore the [Storable] on all members. 37 /// </summary> 38 [Obsolete("not implemnted yet")] 39 AllFieldsAndAllProperties 40 }; 41 6 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable { 42 7 43 8 /// <summary> -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
r3025 r3029 12 12 /// <summary> 13 13 /// Intended for serialization of all custom classes. Classes should have the 14 /// <c>[StorableClass]</c> attribute set and a serialization mode set. 15 /// Optionally selected fields and properties can be marked with the 16 /// <c>[Storable]</c> attribute. 14 /// <c>[StorableClass]</c> attribute set. The default mode is to serialize 15 /// members with the <c>[Storable]</c> attribute set. Alternatively the 16 /// storable mode can be set to <c>AllFields</c>, <c>AllProperties</c> 17 /// or <c>AllFieldsAndAllProperties</c>. 17 18 /// </summary> 18 [StorableClass] 19 [StorableClass] 19 20 public class StorableSerializer : ICompositeSerializer { 20 21 21 22 22 #region ICompositeSerializer implementation … … 30 30 GetStorableConstructor(type) == null) 31 31 return false; 32 return IsEmptyOrStorableType(type, true);32 return StorableReflection.IsEmptyOrStorableType(type, true); 33 33 } 34 34 … … 37 37 GetStorableConstructor(type) == null) 38 38 return "no default constructor and no storable constructor"; 39 if (! IsEmptyOrStorableType(type, true))39 if (!StorableReflection.IsEmptyOrStorableType(type, true)) 40 40 return "class is not marked with the storable class attribute"; 41 41 return "no reason"; … … 71 71 while (iter.MoveNext()) { 72 72 memberDict.Add(iter.Current.Name, iter.Current); 73 } 73 } 74 74 foreach (var accessor in GetStorableAccessors(instance)) { 75 75 if (memberDict.ContainsKey(accessor.Name)) { … … 84 84 #endregion 85 85 86 #region constan ces & private data types86 #region constants & private data types 87 87 88 88 private const BindingFlags ALL_CONSTRUCTORS = 89 89 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 90 91 private const BindingFlags DECLARED_INSTANCE_MEMBERS =92 BindingFlags.Instance |93 BindingFlags.Public |94 BindingFlags.NonPublic |95 BindingFlags.DeclaredOnly;96 97 private sealed class StorableMemberInfo {98 public StorableAttribute Attribute { get; private set; }99 public MemberInfo MemberInfo { get; private set; }100 public string DisentangledName { get; private set; }101 public string FullyQualifiedMemberName {102 get {103 return new StringBuilder()104 .Append(MemberInfo.ReflectedType.FullName)105 .Append('.')106 .Append(MemberInfo.Name)107 .ToString();108 }109 }110 public StorableMemberInfo(StorableAttribute attribute, MemberInfo memberInfo) {111 this.Attribute = attribute;112 this.MemberInfo = memberInfo;113 }114 public override string ToString() {115 return new StringBuilder()116 .Append('[').Append(Attribute).Append(", ")117 .Append(MemberInfo).Append('}').ToString();118 }119 public void SetDisentangledName(string name) {120 DisentangledName = Attribute.Name ?? name;121 }122 public Type GetPropertyDeclaringBaseType() {123 return ((PropertyInfo)MemberInfo).GetGetMethod(true).GetBaseDefinition().DeclaringType;124 }125 }126 90 127 91 private sealed class TypeQuery { … … 141 105 142 106 private MemberCache storableMemberCache = new MemberCache(); 143 private Dictionary<Type, ConstructorInfo> constructorCache = 107 private Dictionary<Type, ConstructorInfo> constructorCache = 144 108 new Dictionary<Type, ConstructorInfo>(); 145 109 146 110 #endregion 147 111 148 #region a uxiliary attribute reflection tools112 #region attribute access 149 113 150 114 private IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) { … … 157 121 if (storableMemberCache.ContainsKey(query)) 158 122 return storableMemberCache[query]; 159 var storablesMembers = GenerateStorableMembers(type, inherited);123 var storablesMembers = StorableReflection.GenerateStorableMembers(type, inherited); 160 124 storableMemberCache[query] = storablesMembers; 161 125 return storablesMembers; 162 126 } 163 } 164 165 private static IEnumerable<StorableMemberInfo> GenerateStorableMembers(Type type, bool inherited) { 166 var storableMembers = new List<StorableMemberInfo>(); 167 if (inherited && type.BaseType != null) 168 storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true)); 169 foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) { 170 foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) { 171 storableMembers.Add(new StorableMemberInfo(attribute, memberInfo)); 172 } 173 } 174 return DisentangleNameMapping(storableMembers); 175 } 176 177 private IEnumerable<DataMemberAccessor> GetStorableAccessors(object obj) { 178 foreach (var memberInfo in GetStorableMembers(obj.GetType())) 179 yield return new DataMemberAccessor( 180 memberInfo.MemberInfo, 181 memberInfo.DisentangledName, 182 memberInfo.Attribute.DefaultValue, 183 obj); 184 } 185 186 private static IEnumerable<StorableMemberInfo> DisentangleNameMapping( 187 IEnumerable<StorableMemberInfo> storableMemberInfos) { 188 var nameGrouping = new Dictionary<string, List<StorableMemberInfo>>(); 189 foreach (StorableMemberInfo storable in storableMemberInfos) { 190 if (!nameGrouping.ContainsKey(storable.MemberInfo.Name)) 191 nameGrouping[storable.MemberInfo.Name] = new List<StorableMemberInfo>(); 192 nameGrouping[storable.MemberInfo.Name].Add(storable); 193 } 194 var memberInfos = new List<StorableMemberInfo>(); 195 foreach (var storableMemberInfoGroup in nameGrouping.Values) { 196 if (storableMemberInfoGroup.Count == 1) { 197 storableMemberInfoGroup[0].SetDisentangledName(storableMemberInfoGroup[0].MemberInfo.Name); 198 memberInfos.Add(storableMemberInfoGroup[0]); 199 } else if (storableMemberInfoGroup[0].MemberInfo.MemberType == MemberTypes.Field) { 200 foreach (var storableMemberInfo in storableMemberInfoGroup) { 201 storableMemberInfo.SetDisentangledName(storableMemberInfo.FullyQualifiedMemberName); 202 memberInfos.Add(storableMemberInfo); 203 } 204 } else { 205 memberInfos.AddRange(MergePropertyAccessors(storableMemberInfoGroup)); 206 } 207 } 208 return memberInfos; 209 } 210 211 private static IEnumerable<StorableMemberInfo> MergePropertyAccessors(List<StorableMemberInfo> members) { 212 var uniqueAccessors = new Dictionary<Type, StorableMemberInfo>(); 213 foreach (var member in members) 214 uniqueAccessors[member.GetPropertyDeclaringBaseType()] = member; 215 if (uniqueAccessors.Count == 1) { 216 var storableMemberInfo = uniqueAccessors.Values.First(); 217 storableMemberInfo.SetDisentangledName(storableMemberInfo.MemberInfo.Name); 218 yield return storableMemberInfo; 219 } else { 220 foreach (var attribute in uniqueAccessors.Values) { 221 attribute.SetDisentangledName(attribute.FullyQualifiedMemberName); 222 yield return attribute; 223 } 224 } 225 } 226 227 private static bool IsEmptyOrStorableType(Type type, bool recusrive) { 228 if (IsEmptyType(type, recusrive)) return true; 229 if (!HastStorableClassAttribute(type)) return false; 230 return !recusrive || type.BaseType == null || IsEmptyOrStorableType(type.BaseType, true); 231 } 232 233 private static bool HastStorableClassAttribute(Type type) { 234 return type.GetCustomAttributes(typeof(StorableClassAttribute), false).Length > 0; 235 } 236 237 private static bool IsEmptyType(Type type, bool recursive) { 238 foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) { 239 if (IsModifiableMember(memberInfo)) return false; 240 } 241 return !recursive || type.BaseType == null || IsEmptyType(type.BaseType, true); 242 } 243 244 private static bool IsModifiableMember(MemberInfo memberInfo) { 245 return memberInfo.MemberType == MemberTypes.Field && IsModifiableField((FieldInfo)memberInfo) || 246 memberInfo.MemberType == MemberTypes.Property && IsModifiableProperty((PropertyInfo)memberInfo); 247 } 248 249 private static bool IsModifiableField(FieldInfo fi) { 250 return !fi.IsLiteral && !fi.IsInitOnly; 251 } 252 253 private static bool IsModifiableProperty(PropertyInfo pi) { 254 return pi.CanWrite; 255 } 127 } 256 128 257 129 private ConstructorInfo GetStorableConstructor(Type type) { … … 273 145 } 274 146 147 private IEnumerable<DataMemberAccessor> GetStorableAccessors(object obj) { 148 return GetStorableMembers(obj.GetType()) 149 .Select(mi => new DataMemberAccessor(mi.MemberInfo, mi.DisentangledName, mi.DefaultValue, obj)); 150 } 151 275 152 #endregion 153 276 154 } 155 277 156 }
Note: See TracChangeset
for help on using the changeset viewer.