Changeset 1938
- Timestamp:
- 05/28/09 18:06:43 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Persistence
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/DataMemberAccessor.cs
r1852 r1938 12 12 public readonly object DefaultValue; 13 13 14 public DataMemberAccessor( 15 MemberInfo memberInfo, 16 StorableAttribute storableAttribute, 17 object obj) { 14 public DataMemberAccessor(MemberInfo memberInfo, string name, object defaultvalue, object obj) { 15 Name = name; 16 DefaultValue = defaultvalue; 18 17 if (memberInfo.MemberType == MemberTypes.Field) { 19 18 FieldInfo fieldInfo = (FieldInfo)memberInfo; … … 32 31 "The Storable attribute can only be applied to fields and properties."); 33 32 } 34 Name = storableAttribute.Name ?? memberInfo.Name;35 DefaultValue = storableAttribute.DefaultValue;36 33 } 37 34 38 public DataMemberAccessor( 39 string name, object defaultValue, 35 public DataMemberAccessor(string name, object defaultValue, 40 36 Func<object> getter, Action<object> setter) { 41 37 Name = name; … … 61 57 62 58 public override string ToString() { 63 return String.Format("DataMember ({0}, {1}, {2}, {3})",59 return String.Format("DataMemberAccessor({0}, {1}, {2}, {3})", 64 60 Name, 65 61 DefaultValue ?? "<null>", -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs
r1893 r1938 2 2 using System.Collections.Generic; 3 3 using System.Reflection; 4 using System.Text; 4 5 5 6 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable { … … 14 15 public object DefaultValue { get; set; } 15 16 17 public override string ToString() { 18 StringBuilder sb = new StringBuilder(); 19 sb.Append("[Storable"); 20 if (Name != null || DefaultValue != null) 21 sb.Append('('); 22 if (Name != null) { 23 sb.Append("Name = \"").Append(Name).Append("\""); 24 if (DefaultValue != null) 25 sb.Append(", "); 26 } 27 if (DefaultValue != null) 28 sb.Append("DefaultValue = \"").Append(DefaultValue).Append("\""); 29 if (Name != null || DefaultValue != null) 30 sb.Append(')'); 31 sb.Append(']'); 32 return sb.ToString(); 33 } 34 16 35 private const BindingFlags instanceMembers = 17 36 BindingFlags.Instance | … … 20 39 BindingFlags.DeclaredOnly; 21 40 22 private static Dictionary<KeyValuePair<Type, bool>, IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>> memberCache = 23 new Dictionary<KeyValuePair<Type, bool>, IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>>(); 41 public sealed class StorableMemberInfo { 42 public StorableAttribute Attribute { get; private set; } 43 public MemberInfo MemberInfo { get; private set; } 44 public StorableMemberInfo(StorableAttribute attribute, MemberInfo memberInfo) { 45 this.Attribute = attribute; 46 this.MemberInfo = memberInfo; 47 } 48 public override string ToString() { 49 return new StringBuilder() 50 .Append('[').Append(Attribute).Append(", ") 51 .Append(MemberInfo).Append('}').ToString(); 52 } 53 } 24 54 25 public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>> GetStorableMembers(Type type) { 55 sealed class TypeQuery { 56 public Type Type { get; private set; } 57 public bool Inherited { get; private set; } 58 public TypeQuery(Type type, bool inherited) { 59 this.Type = type; 60 this.Inherited = inherited; 61 } 62 } 63 64 sealed class MemberCache : Dictionary<TypeQuery, IEnumerable<StorableMemberInfo>> { } 65 66 private static MemberCache memberCache = new MemberCache(); 67 68 public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) { 26 69 return GetStorableMembers(type, true); 27 70 } 28 71 29 public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>> 30 GetStorableMembers(Type type, bool inherited) { 31 var query = new KeyValuePair<Type, bool>(type, inherited); 72 public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type, bool inherited) { 73 var query = new TypeQuery(type, inherited); 32 74 if (memberCache.ContainsKey(query)) 33 75 return memberCache[query]; 34 IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>>storablesMembers = GenerateStorableMembers(type, inherited);76 var storablesMembers = GenerateStorableMembers(type, inherited); 35 77 memberCache[query] = storablesMembers; 36 78 return storablesMembers; 37 79 } 38 80 39 public static IEnumerable<KeyValuePair<StorableAttribute, MemberInfo>> 40 GenerateStorableMembers(Type type, bool inherited) { 41 List<KeyValuePair<StorableAttribute, MemberInfo>> storableMembers = 42 new List<KeyValuePair<StorableAttribute, MemberInfo>>(); 81 private static IEnumerable<StorableMemberInfo> GenerateStorableMembers(Type type, bool inherited) { 82 var storableMembers = new List<StorableMemberInfo>(); 43 83 if (inherited && type.BaseType != null) 44 storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true)); 84 storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true)); 45 85 foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) { 46 86 foreach (object attribute in memberInfo.GetCustomAttributes(false)) { 47 StorableAttribute storableAttribute = 48 attribute as StorableAttribute; 87 StorableAttribute storableAttribute = attribute as StorableAttribute; 49 88 if (storableAttribute != null) { 50 storableMembers.Add(new KeyValuePair<StorableAttribute, MemberInfo>(storableAttribute, memberInfo));89 storableMembers.Add(new StorableMemberInfo(storableAttribute, memberInfo)); 51 90 } 52 91 } … … 56 95 57 96 public static Dictionary<string, DataMemberAccessor> GetStorableAccessors(object obj) { 58 Dictionary<string, DataMemberAccessor> storableAccessors = 59 new Dictionary<string, DataMemberAccessor>(); 60 foreach (KeyValuePair<StorableAttribute, MemberInfo> pair in GetStorableMembers(obj.GetType())) { 61 storableAccessors.Add(pair.Value.Name, 62 new DataMemberAccessor(pair.Value, pair.Key, obj)); 97 var storableAccessors = new Dictionary<string, DataMemberAccessor>(); 98 var nameMapping = createNameMapping(obj.GetType()); 99 var finalNameMapping = analyzeNameMapping(nameMapping); 100 foreach (var mapping in finalNameMapping) { 101 storableAccessors.Add(mapping.Value.Attribute.Name ?? mapping.Key, 102 new DataMemberAccessor( 103 mapping.Value.MemberInfo, 104 mapping.Value.Attribute.Name ?? mapping.Key, 105 mapping.Value.Attribute.DefaultValue, 106 obj)); 63 107 } 64 108 return storableAccessors; 65 109 } 110 111 private static Dictionary<string, StorableMemberInfo> analyzeNameMapping( 112 Dictionary<string, List<StorableMemberInfo>> nameMapping) { 113 var finalNameMapping = new Dictionary<string, StorableMemberInfo>(); 114 foreach (var attributes in nameMapping) { 115 if (attributes.Value.Count == 1) { 116 finalNameMapping[attributes.Key] = attributes.Value[0]; 117 } else if (attributes.Value[0].MemberInfo.MemberType == MemberTypes.Field) { 118 foreach (var attribute in attributes.Value) { 119 StringBuilder sb = new StringBuilder(); 120 sb.Append(attribute.MemberInfo.ReflectedType.FullName).Append('.') 121 .Append(attribute.MemberInfo.Name); 122 finalNameMapping[sb.ToString()] = attribute; 123 } 124 } else { 125 var uniqueAccessors = new Dictionary<Type, StorableMemberInfo>(); 126 foreach (var attribute in attributes.Value) { 127 uniqueAccessors[((PropertyInfo)attribute.MemberInfo).GetGetMethod(true).GetBaseDefinition().DeclaringType] = 128 attribute; 129 } 130 if (uniqueAccessors.Count == 1) { 131 var it = uniqueAccessors.Values.GetEnumerator(); 132 it.MoveNext(); 133 finalNameMapping[attributes.Key] = it.Current; 134 } else { 135 foreach (var attribute in uniqueAccessors.Values) { 136 StringBuilder sb = new StringBuilder(); 137 sb.Append(attribute.MemberInfo.DeclaringType.FullName).Append('.') 138 .Append(attribute.MemberInfo.Name); 139 finalNameMapping[sb.ToString()] = attribute; 140 } 141 } 142 } 143 } 144 return finalNameMapping; 145 } 146 147 private static Dictionary<string, List<StorableMemberInfo>> createNameMapping(Type type) { 148 var nameMapping = new Dictionary<string, List<StorableMemberInfo>>(); 149 foreach (StorableMemberInfo storable in GetStorableMembers(type)) { 150 if (!nameMapping.ContainsKey(storable.MemberInfo.Name)) 151 nameMapping[storable.MemberInfo.Name] = new List<StorableMemberInfo>(); 152 nameMapping[storable.MemberInfo.Name].Add(storable); 153 } 154 return nameMapping; 155 } 66 156 } 67 157 } -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
r1852 r1938 34 34 public IEnumerable<Tag> Decompose(object obj) { 35 35 foreach (var mapping in StorableAttribute.GetStorableAccessors(obj)) { 36 yield return new Tag(mapping. Value.Name ?? mapping.Key, mapping.Value.Get());36 yield return new Tag(mapping.Key, mapping.Value.Get()); 37 37 } 38 38 } … … 49 49 } 50 50 foreach (var mapping in StorableAttribute.GetStorableAccessors(instance)) { 51 string name = mapping. Value.Name ?? mapping.Key;51 string name = mapping.Key; 52 52 if (memberDict.ContainsKey(name)) { 53 53 mapping.Value.Set(memberDict[name].Value); -
trunk/sources/HeuristicLab.Persistence/UnitTests/StorableAttributeTests.cs
r1823 r1938 4 4 using Microsoft.VisualStudio.TestTools.UnitTesting; 5 5 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 6 using System.Reflection; 6 7 7 8 namespace HeuristicLab.Persistence.Test { … … 19 20 } 20 21 22 class Base { 23 public string baseName; 24 [Storable] 25 public virtual string Name { 26 get { return "Base"; } 27 set { baseName = value; } 28 } 29 } 30 31 class Override : Base { 32 [Storable] 33 public override string Name { 34 get { return "Override"; } 35 set { base.Name = value; } 36 } 37 } 38 39 [EmptyStorableClass] 40 class Intermediate : Override { 41 } 42 43 class New : Intermediate { 44 public string newName; 45 [Storable] 46 public new string Name { 47 get { return "New"; } 48 set { newName = value; } 49 } 50 } 51 21 52 [TestClass] 22 53 public class AttributeTest { … … 26 57 DemoClass t = new DemoClass(); 27 58 Dictionary<string, DataMemberAccessor> accessors = StorableAttribute.GetStorableAccessors(t); 28 Assert.IsTrue(accessors.ContainsKey(" o"));59 Assert.IsTrue(accessors.ContainsKey("TestProperty")); 29 60 Assert.IsTrue(accessors.ContainsKey("x")); 30 61 Assert.IsFalse(accessors.ContainsKey("y")); 31 62 object o = new object(); 32 63 t.o = o; 33 Assert.AreSame(accessors[" o"].Get(), o);64 Assert.AreSame(accessors["TestProperty"].Get(), o); 34 65 t.x = 12; 35 66 Assert.AreEqual(accessors["x"].Get(), 12); 36 67 t.y = 312890; 37 accessors[" o"].Set(null);68 accessors["TestProperty"].Set(null); 38 69 Assert.IsNull(t.o); 39 70 accessors["x"].Set(123); … … 41 72 } 42 73 74 [TestMethod] 75 public void TestInheritance() { 76 New n = new New(); 77 var accessors = StorableAttribute.GetStorableAccessors(n); 78 var accessDict = new Dictionary<string, DataMemberAccessor>(); 79 foreach (var accessor in accessors) // assert uniqueness 80 accessDict.Add(accessor.Key, accessor.Value); 81 Assert.IsTrue(accessDict.ContainsKey(typeof(New).FullName + ".Name")); 82 Assert.IsTrue(accessDict.ContainsKey(typeof(Override).FullName + ".Name")); 83 Assert.AreEqual("New", accessDict[typeof(New).FullName + ".Name"].Get()); 84 Assert.AreEqual("Override", accessDict[typeof(Override).FullName + ".Name"].Get()); 85 } 86 43 87 } 44 88 -
trunk/sources/HeuristicLab.Persistence/UnitTests/UseCases.cs
r1823 r1938 16 16 using HeuristicLab.Persistence.Auxiliary; 17 17 using System.Text.RegularExpressions; 18 using HeuristicLab.Persistence.Test; 18 19 19 20 namespace HeuristicLab.Persistence.UnitTest { … … 541 542 } 542 543 544 [TestMethod] 545 public void InheritanceTest() { 546 New n = new New(); 547 XmlGenerator.Serialize(n, tempFile); 548 New nn = (New)XmlParser.Deserialize(tempFile); 549 Assert.AreEqual(n.Name, nn.Name); 550 Assert.AreEqual(((Override)n).Name, ((Override)nn).Name); 551 } 552 543 553 [ClassInitialize] 544 554 public static void Initialize(TestContext testContext) {
Note: See TracChangeset
for help on using the changeset viewer.