Changeset 16210


Ignore:
Timestamp:
10/03/18 17:48:20 (9 months ago)
Author:
jkarder
Message:

#2520: worked on new persistence

  • added cache for different attributes
  • refactored StorableTypeBoxTransformer
  • implemented paths for Storable members
  • implemented more unit tests
Location:
branches/PersistenceReintegration
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableAttribute.cs

    r15035 r16210  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Reflection;
    24 using System.Text;
    2525
    2626namespace HeuristicLab.Persistence {
    27 
    28 
    2927  /// <summary>
    3028  /// Mark the member of a class to be considered by the <c>StorableSerializer</c>.
     
    3634    AttributeTargets.Field | AttributeTargets.Property,
    3735    AllowMultiple = false,
    38     Inherited = false)]
    39   public class StorableAttribute : Attribute {
    40     public static bool IsStorable(MemberInfo memberInfo) {
    41       return Attribute.IsDefined(memberInfo, typeof(StorableAttribute), false);
    42     }
    43     public static StorableAttribute GetStorableAttribute(MemberInfo memberInfo) {
    44       return (StorableAttribute)Attribute.GetCustomAttribute(memberInfo, typeof(StorableAttribute), false);
    45     }
     36    Inherited = false
     37  )]
     38  public sealed class StorableAttribute : Attribute {
     39    private static IDictionary<MemberInfo, StorableAttribute> attributeCache = new Dictionary<MemberInfo, StorableAttribute>();
    4640
     41    #region Properties
    4742    /// <summary>
    4843    /// An optional name for this member that will be used during serialization.
     
    6762    /// deserialized (setter only) but not serialized again.
    6863    /// </summary>
     64    [Obsolete("Use OldName instead.")]
    6965    public bool AllowOneWay { get; set; }
    7066
    71     /// <summary>
    72     /// Returns a <see cref="System.String"/> that represents this instance.
    73     /// </summary>
    74     /// <returns>
    75     /// A <see cref="System.String"/> that represents this instance.
    76     /// </returns>
    77     public override string ToString() {
    78       StringBuilder sb = new StringBuilder();
    79       sb.Append("[Storable");
    80       if (Name != null || DefaultValue != null)
    81         sb.Append('(');
    82       if (Name != null) {
    83         sb.Append("Name = \"").Append(Name).Append("\"");
    84         if (DefaultValue != null)
    85           sb.Append(", ");
     67    public string OldName { get; set; }
     68    #endregion
     69
     70    public static bool IsStorable(MemberInfo memberInfo) {
     71      return GetStorableAttribute(memberInfo) != null;
     72    }
     73    public static StorableAttribute GetStorableAttribute(MemberInfo memberInfo) {
     74      StorableAttribute attrib;
     75
     76      if (!attributeCache.TryGetValue(memberInfo, out attrib)) {
     77        attrib = (StorableAttribute)GetCustomAttribute(memberInfo, typeof(StorableAttribute), false);
     78        if (attrib != null) attributeCache[memberInfo] = attrib;
    8679      }
    87       if (DefaultValue != null)
    88         sb.Append("DefaultValue = \"").Append(DefaultValue).Append("\"");
    89       if (Name != null || DefaultValue != null)
    90         sb.Append(')');
    91       sb.Append(']');
    92       return sb.ToString();
     80
     81      return attrib;
    9382    }
    9483  }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableHookAttribute.cs

    r14927 r16210  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Linq;
    2425using System.Reflection;
    2526
    2627namespace HeuristicLab.Persistence {
    27 
    28 
    2928  /// <summary>
    3029  /// Indicates the time at which the hook should be invoked.
    3130  /// </summary>
    3231  public enum HookType {
    33 
    3432    /// <summary>
    3533    /// States that this hook should be called before the storable
     
    4543  };
    4644
    47 
    4845  /// <summary>
    4946  /// Mark methods that should be called at certain times during
     
    5350  [StorableType("983bf558-1458-4129-b018-7e121ac3840e")]
    5451  public sealed class StorableHookAttribute : Attribute {
    55     public static bool IsStorableHook(MethodInfo methodInfo) {
    56       return Attribute.IsDefined(methodInfo, typeof(StorableHookAttribute), false);
    57     }
    58     public static StorableHookAttribute[] GetStorableHookAttributes(MethodInfo methodInfo) {
    59       return Attribute.GetCustomAttributes(methodInfo, false).OfType<StorableHookAttribute>().ToArray();
    60     }
     52    private static IDictionary<MethodInfo, StorableHookAttribute[]> attributeCache = new Dictionary<MethodInfo, StorableHookAttribute[]>();
    6153
    62     private readonly HookType hookType;
     54    #region Properties
    6355    /// <summary>
    6456    /// Gets the type of the hook.
     
    6860      get { return hookType; }
    6961    }
     62    private readonly HookType hookType;
     63    #endregion
    7064
    7165    /// <summary>
     
    7771      this.hookType = hookType;
    7872    }
     73
     74    public static bool IsStorableHook(MethodInfo methodInfo) {
     75      return GetStorableHookAttributes(methodInfo) != null;
     76    }
     77
     78    public static StorableHookAttribute[] GetStorableHookAttributes(MethodInfo methodInfo) {
     79      StorableHookAttribute[] attribs;
     80
     81      if (!attributeCache.TryGetValue(methodInfo, out attribs)) {
     82        attribs = (StorableHookAttribute[])GetCustomAttributes(methodInfo, typeof(StorableHookAttribute), false);
     83        if (attribs.Any()) attributeCache[methodInfo] = attribs;
     84      }
     85
     86      return attribs;
     87    }
    7988  }
    8089}
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs

    r15986 r16210  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324
    2425namespace HeuristicLab.Persistence {
    25 
    2626  /// <summary>
    2727  /// Mark a class to be considered by the <c>StorableSerializer</c>.
    2828  /// </summary>
    29   [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
     29  [AttributeUsage(
     30    AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate,
     31    Inherited = false,
     32    AllowMultiple = false
     33  )]
    3034  public sealed class StorableTypeAttribute : Attribute {
     35    private static IDictionary<Type, StorableTypeAttribute> attributeCache = new Dictionary<Type, StorableTypeAttribute>();
    3136
    32 
     37    #region Properties
    3338    /// <summary>
    3439    /// Specify how members are selected for serialization.
     
    3641    public StorableMemberSelection MemberSelection { get; private set; }
    3742
     43    /// <summary>
     44    /// The GUID that identifies the type.
     45    /// </summary>
     46    /// <value>The GUID.</value>
    3847    public Guid Guid { get; private set; }
     48    #endregion
    3949
    4050    /// <summary>
     
    6474    /// <returns></returns>
    6575    public static bool IsStorableType(Type type) {
    66       object[] attribs = type.GetCustomAttributes(typeof(StorableTypeAttribute), false);
    67       return attribs.Length > 0;
     76      return GetStorableTypeAttribute(type) != null;
    6877    }
    6978
    7079    public static StorableTypeAttribute GetStorableTypeAttribute(Type type) {
    71       return (StorableTypeAttribute)Attribute.GetCustomAttribute(type, typeof(StorableTypeAttribute), false);
     80      StorableTypeAttribute attrib;
     81
     82      if (!attributeCache.TryGetValue(type, out attrib)) {
     83        attrib = (StorableTypeAttribute)GetCustomAttribute(type, typeof(StorableTypeAttribute), false);
     84        if (attrib != null) attributeCache[type] = attrib;
     85      }
     86
     87      return attrib;
    7288    }
    73 
    7489  }
    7590}
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs

    r15986 r16210  
    4242      constructor = null;
    4343      Type = type;
     44      StorableTypeAttribute = StorableTypeAttribute.GetStorableTypeAttribute(type);
    4445      Fields = Enumerable.Empty<ComponentInfo>();
    4546      Properties = Enumerable.Empty<ComponentInfo>();
     
    5657    private void Reflect() {
    5758      var type = Type;
    58       StorableTypeAttribute = StorableTypeAttribute.GetStorableTypeAttribute(type);
     59
    5960      if (StorableTypeAttribute != null) {
    6061        string guidPrefix = StorableTypeAttribute.Guid.ToString().ToUpper();
     
    7879
    7980          foreach (var field in fieldInfos) {
     81            var name = field.Name;
    8082            var attrib = StorableAttribute.GetStorableAttribute(field);
    81             var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
     83
     84            if (attrib != null) {
     85              if (!string.IsNullOrEmpty(attrib.Name) && !string.IsNullOrEmpty(attrib.OldName))
     86                throw new PersistenceException("Cannot use Name and OldName at the same time.");
     87
     88              if (!string.IsNullOrEmpty(attrib.Name)) name = attrib.Name;
     89              else if (!string.IsNullOrEmpty(attrib.OldName)) name = attrib.OldName;
     90            }
     91
     92            var nameParts = name.Split('.').ToArray();
     93            var sourceType = type;
     94            var tmpGuid = Guid.Empty;
     95
     96            for (int i = 0; i < nameParts.Length; i++) {
     97              var part = nameParts[i];
     98              if (part == "base") sourceType = sourceType.BaseType;
     99              else if (Guid.TryParse(part, out tmpGuid)) {
     100                if (i != 0 || nameParts.Length != 2) throw new PersistenceException("Invalid field path specified.");
     101                guidPrefix = tmpGuid.ToString().ToUpper();
     102                break;
     103              } else if (i != nameParts.Length - 1)
     104                throw new PersistenceException("Invalid field path specified.");
     105              else break;
     106            }
     107
     108            if (sourceType != type) {
     109              name = nameParts[nameParts.Length - 1];
     110              guidPrefix = StorableTypeAttribute.GetStorableTypeAttribute(sourceType).Guid.ToString().ToUpper();
     111            } else if (tmpGuid != Guid.Empty) {
     112              name = nameParts[nameParts.Length - 1];
     113            }
     114
    82115            fields.Add(new ComponentInfo(name, guidPrefix + "." + name, field, attrib, true, true));
    83116          }
     
    93126
    94127          foreach (var property in propertyInfos) {
     128            var name = property.Name;
    95129            var attrib = StorableAttribute.GetStorableAttribute(property);
    96             if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay))
    97               throw new PersistenceException("Properties must be readable and writable or have one way serialization explicitly enabled.");
    98 
    99             var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
     130
     131            if (attrib != null) {
     132              if (!string.IsNullOrEmpty(attrib.Name) && !string.IsNullOrEmpty(attrib.OldName))
     133                throw new PersistenceException("Cannot use Name and OldName at the same time.");
     134
     135              if (attrib.AllowOneWay && !string.IsNullOrEmpty(attrib.OldName))
     136                throw new PersistenceException("Cannot use AllowOneWay and OldName at the same time.");
     137
     138              if (!string.IsNullOrEmpty(attrib.Name)) name = attrib.Name;
     139              else if (!string.IsNullOrEmpty(attrib.OldName)) name = attrib.OldName;
     140            }
     141
     142            if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay && string.IsNullOrEmpty(attrib.OldName)))
     143              throw new PersistenceException("Properties must be readable and writable or have one way serialization explicitly enabled or use OldName.");
     144
     145            var nameParts = name.Split('.').ToArray();
     146            var sourceType = type;
     147            var tmpGuid = Guid.Empty;
     148
     149            for (int i = 0; i < nameParts.Length; i++) {
     150              var part = nameParts[i];
     151              if (part == "base") sourceType = sourceType.BaseType;
     152              else if (Guid.TryParse(part, out tmpGuid)) {
     153                if (i != 0 || nameParts.Length != 2) throw new PersistenceException("Invalid field path specified.");
     154                guidPrefix = tmpGuid.ToString().ToUpper();
     155                break;
     156              } else if (i != nameParts.Length - 1)
     157                throw new PersistenceException("Invalid field path specified.");
     158              else break;
     159            }
     160
     161            if (sourceType != type) {
     162              name = nameParts[nameParts.Length - 1];
     163              guidPrefix = StorableTypeAttribute.GetStorableTypeAttribute(sourceType).Guid.ToString().ToUpper();
     164            } else if (tmpGuid != Guid.Empty) {
     165              name = nameParts[nameParts.Length - 1];
     166            }
     167
    100168            properties.Add(new ComponentInfo(name, guidPrefix + "." + name, property, attrib, property.CanRead, property.CanWrite));
    101169          }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs

    r15986 r16210  
    473473  [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 303)]
    474474  [StorableType("BA53DF84-DC97-4D8D-A493-868972ED1002")]
    475   internal sealed class DictionaryTransformer : BoxTransformer<object> {
     475  internal sealed class IDictionary : BoxTransformer<object> {
    476476    public override bool CanTransformType(Type type) {
    477477      return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition();
     
    480480    protected override void Populate(Box box, object value, Mapper mapper) {
    481481      var kvps = box.KeyValuePairs;
    482       foreach (DictionaryEntry item in (IDictionary)value)
     482      foreach (DictionaryEntry item in (System.Collections.IDictionary)value)
    483483        kvps.Add(mapper.GetBoxId(item.Key), mapper.GetBoxId(item.Value));
    484484
     
    855855          if (attrib != null && attrib.DefaultValue != null)
    856856            fieldInfo.SetValue(obj, attrib.DefaultValue);
     857
     858          object value;
     859          if (!dict.TryGetValue(componentInfo.FullName, out value)) continue;
     860
     861          var field = (FieldInfo)componentInfo.MemberInfo;
     862          field.SetValue(obj, value);
    857863        }
     864
    858865        foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
    859866          var attrib = componentInfo.StorableAttribute;
     
    861868          if (attrib != null && attrib.DefaultValue != null)
    862869            property.SetValue(obj, attrib.DefaultValue, null);
     870
     871          object value;
     872          if (!dict.TryGetValue(componentInfo.FullName, out value)) continue;
     873
     874          var prop = (PropertyInfo)componentInfo.MemberInfo;
     875          prop.SetValue(obj, value, null);
    863876        }
    864877
    865878        // set all members
    866         foreach (var kvp in dict) {
    867           string key = kvp.Key;
    868           object val = kvp.Value;
    869 
    870           string[] keyParts = key.Split('.');
    871           var guid = Guid.Parse(keyParts[0]);
    872           string ident = keyParts[1];
    873 
    874           if (guid != typeInfo.StorableTypeAttribute.Guid) continue;
    875 
    876           var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == ident);
    877           if (fieldInfo != null) {
    878             var field = (FieldInfo)fieldInfo.MemberInfo;
    879             field.SetValue(obj, val);
    880             //dict.Remove(guid.ToString().ToUpperInvariant() + "." + fieldInfo.Name); // only for consistency check
    881             continue;
    882           }
    883 
    884           var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(fi => fi.Name == ident);
    885           if (propInfo != null) {
    886             var prop = (PropertyInfo)propInfo.MemberInfo;
    887             prop.SetValue(obj, val, null);
    888             //dict.Remove(guid.ToString().ToUpperInvariant() + "." + propInfo.Name); // only for consistency check
    889             continue;
    890           }
    891         }
     879        //foreach (var kvp in dict) {
     880        //  string key = kvp.Key;
     881        //  object val = kvp.Value;
     882
     883        //  string[] keyParts = key.Split('.');
     884        //  var guid = Guid.Parse(keyParts[0]);
     885        //  string ident = keyParts[1];
     886
     887        //  if (guid != typeInfo.StorableTypeAttribute.Guid) continue;
     888
     889        //  var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == ident);
     890        //  if (fieldInfo != null) {
     891        //    var field = (FieldInfo)fieldInfo.MemberInfo;
     892        //    field.SetValue(obj, val);
     893        //    //dict.Remove(guid.ToString().ToUpperInvariant() + "." + fieldInfo.Name); // only for consistency check
     894        //    continue;
     895        //  }
     896
     897        //  var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(fi => fi.Name == ident);
     898        //  if (propInfo != null) {
     899        //    var prop = (PropertyInfo)propInfo.MemberInfo;
     900        //    prop.SetValue(obj, val, null);
     901        //    //dict.Remove(guid.ToString().ToUpperInvariant() + "." + propInfo.Name); // only for consistency check
     902        //    continue;
     903        //  }
     904        //}
    892905
    893906        //var undefinedMembers = dict.Where(x => Guid.Parse(x.Key.Split('.')[0]) == typeInfo.StorableTypeAttribute.Guid);
  • branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs

    r15986 r16210  
    3232using System.Threading.Tasks;
    3333using HeuristicLab.Algorithms.GeneticAlgorithm;
    34 using HeuristicLab.Core;
    3534using HeuristicLab.Data;
    3635using HeuristicLab.Persistence;
     
    327326    }
    328327
    329     public static void DeregisterType(Type type) {
    330       var typeInfo = GetTypeInfo(type);
    331       type2Guid.Remove(guid2Type[typeInfo.StorableTypeAttribute.Guid]);
    332       guid2Type.Remove(typeInfo.StorableTypeAttribute.Guid);
     328    public static void DeregisterType(Guid guid) {
     329      if (!guid2Type.ContainsKey(guid)) return;
     330      type2Guid.Remove(guid2Type[guid]);
     331      guid2Type.Remove(guid);
    333332    }
    334333
     
    337336    }
    338337
    339     //public static void RemoveTypeInfo(Type type) {
    340     //  typeInfos.Remove(typeof(ConversionA));
     338    private static void ReplaceTypeImplementation(Type old, Guid oldGuid, Type @new) {
     339      DeregisterType(oldGuid);
     340      DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(@new).Guid);
     341
     342      RegisterType(oldGuid, @new);
     343      SetTypeGuid(@new, oldGuid);
     344      typeInfos.Remove(old);
     345    }
     346
     347    //public static Guid GetTypeGuid(Type type) {
     348    //  var typeInfo = GetTypeInfo(type);
     349    //  return typeInfo.StorableTypeAttribute.Guid;
    341350    //}
    342 
    343     public static Guid GetTypeGuid(Type type) {
    344       var typeInfo = GetTypeInfo(type);
    345       return typeInfo.StorableTypeAttribute.Guid;
    346     }
    347351
    348352    public static void SetTypeGuid(Type type, Guid guid) {
    349353      var typeInfo = GetTypeInfo(type);
    350354      guidPropertyInfo.SetValue(typeInfo.StorableTypeAttribute, guid);
     355
     356      var reflectMethod = typeInfo.GetType().GetMethod("Reflect", BindingFlags.NonPublic | BindingFlags.Instance);
     357      reflectMethod.Invoke(typeInfo, new object[0]);
    351358    }
    352359    #endregion
     
    26702677    //}
    26712678    #endregion
     2679
     2680    [StorableType("28A5F6B8-49AF-4C6A-AF0E-F92EB4511722")]
     2681    private class PersistenceTestA0 {
     2682      [Storable]
     2683      public IntValue v;
     2684    }
     2685
     2686    [StorableType("00000000-0000-0000-0000-0000000000A1")]
     2687    private class PersistenceTestA1 {
     2688      [Storable(OldName = "v")]
     2689      private IntValue v1 {
     2690        set { v = value.Value; }
     2691      }
     2692
     2693      [Storable(Name = "v2")]
     2694      public int v;
     2695    }
     2696
     2697    [StorableType("00000000-0000-0000-0000-0000000000A2")]
     2698    private class PersistenceTestA2 {
     2699      [Storable(OldName = "v")]
     2700      private IntValue v1 {
     2701        set { v2 = value.Value; }
     2702      }
     2703
     2704      [Storable(OldName = "v2")]
     2705      private int v2 {
     2706        set { v = (double)value; }
     2707      }
     2708
     2709      [Storable(Name = "v3")]
     2710      public double v;
     2711    }
     2712
     2713    [TestMethod]
     2714    [TestCategory("PersistenceNew.Conversion")]
     2715    [TestProperty("Time", "short")]
     2716    public void TestConversionSample1() {
     2717      var v0Type = typeof(PersistenceTestA0);
     2718      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
     2719
     2720      var test = new Func<PersistenceTestA0>(() => {
     2721        return new PersistenceTestA0() { v = new IntValue(1337) };
     2722      });
     2723
     2724      ProtoBufSerializer serializer = new ProtoBufSerializer();
     2725      var v0 = test();
     2726      serializer.Serialize(v0, tempFile);
     2727
     2728      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestA1));
     2729
     2730      var v1 = (PersistenceTestA1)serializer.Deserialize(tempFile);
     2731      Assert.AreEqual(v0.v.Value, v1.v);
     2732
     2733      ReplaceTypeImplementation(typeof(PersistenceTestA1), v0Guid, typeof(PersistenceTestA2));
     2734
     2735      var v2 = (PersistenceTestA2)serializer.Deserialize(tempFile);
     2736      Assert.AreEqual(v2.v, v1.v);
     2737    }
     2738
     2739    [StorableType("7DCED655-D724-492E-9C6A-A22B376BADB2")]
     2740    private class PersistenceTestB0 {
     2741      [Storable]
     2742      public Point p;
     2743    }
     2744
     2745    [StorableType("00000000-0000-0000-0000-0000000000B1")]
     2746    private class PersistenceTestB1 {
     2747      [Storable(AllowOneWay = true)]
     2748      private Point p {
     2749        set {
     2750          x = value.X;
     2751          y = value.Y;
     2752        }
     2753      }
     2754
     2755      [Storable]
     2756      public int x;
     2757
     2758      [Storable]
     2759      public int y;
     2760    }
     2761
     2762    [StorableType("00000000-0000-0000-0000-0000000000B2")]
     2763    private class PersistenceTestB2 {
     2764      [Storable(AllowOneWay = true)]
     2765      private int x { set { p = new Point(value, p.Y); } }
     2766
     2767      [Storable(AllowOneWay = true)]
     2768      private int y { set { p = new Point(p.X, value); } }
     2769
     2770      [Storable]
     2771      public Point p { get; private set; }
     2772    }
     2773
     2774    [TestMethod]
     2775    [TestCategory("PersistenceNew.Conversion")]
     2776    [TestProperty("Time", "short")]
     2777    public void TestConversionSample2() {
     2778      var v0Type = typeof(PersistenceTestB0);
     2779      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
     2780
     2781      var test = new Func<PersistenceTestB0>(() => {
     2782        return new PersistenceTestB0() { p = new Point(1, 2) };
     2783      });
     2784
     2785      ProtoBufSerializer serializer = new ProtoBufSerializer();
     2786      var v0 = test();
     2787
     2788      // seriealize B0, deserialize B0
     2789      serializer.Serialize(v0, tempFile);
     2790      var newV0 = (PersistenceTestB0)serializer.Deserialize(tempFile);
     2791      Assert.AreEqual(v0.p.X, newV0.p.X);
     2792      Assert.AreEqual(v0.p.Y, newV0.p.Y);
     2793
     2794      // serialize B0, deserialize B1
     2795      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB1));
     2796      var v1 = (PersistenceTestB1)serializer.Deserialize(tempFile);
     2797      Assert.AreEqual(v0.p.X, v1.x);
     2798      Assert.AreEqual(v0.p.Y, v1.y);
     2799
     2800      // serialize B0, deserialize B2
     2801      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB2));
     2802      var v2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
     2803      Assert.AreEqual(v0.p.X, v2.p.X);
     2804      Assert.AreEqual(v0.p.Y, v2.p.Y);
     2805
     2806      // serialize B1, deserialize B1
     2807      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB1));
     2808      serializer.Serialize(v1, tempFile);
     2809      var newV1 = (PersistenceTestB1)serializer.Deserialize(tempFile);
     2810      Assert.AreEqual(v1.x, newV1.x);
     2811      Assert.AreEqual(v1.y, newV1.y);
     2812
     2813      // serialize B1, deserialize B2
     2814      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB2));
     2815      v2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
     2816      Assert.AreEqual(v1.x, v2.p.X);
     2817      Assert.AreEqual(v1.y, v2.p.Y);
     2818
     2819      // serialize B2, deserialize B2
     2820      serializer.Serialize(v2, tempFile);
     2821      var newV2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
     2822      Assert.AreEqual(v2.p.X, newV2.p.X);
     2823      Assert.AreEqual(v2.p.Y, newV2.p.Y);
     2824    }
     2825
     2826    [StorableType("FB649DF5-5B99-45DE-807A-27E86CB22F4B")]
     2827    private class PersistenceTestC0 {
     2828      [Storable]
     2829      public PersistenceTestC0 neighbor;
     2830
     2831      [Storable]
     2832      public int value;
     2833    }
     2834
     2835    [StorableType("00000000-0000-0000-0000-0000000000C1")]
     2836    private class PersistenceTestC1 {
     2837      [Storable]
     2838      private PersistenceTestC1 neighbor;
     2839
     2840      [Storable]
     2841      public int neighborValue;
     2842
     2843      [Storable]
     2844      public int value;
     2845
     2846      [StorableHook(HookType.AfterDeserialization)]
     2847      private void AfterDeserialization() {
     2848        if (neighbor != null)
     2849          neighborValue = neighbor.value;
     2850      }
     2851    }
     2852
     2853    [TestMethod]
     2854    [TestCategory("PersistenceNew.Conversion")]
     2855    [TestProperty("Time", "short")]
     2856    public void TestConversionSample3() {
     2857      var v0Type = typeof(PersistenceTestC0);
     2858      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
     2859
     2860      var test = new Func<PersistenceTestC0>(() => {
     2861        var c0 = new PersistenceTestC0() {
     2862          value = 90
     2863        };
     2864        c0.neighbor = c0;
     2865        return c0;
     2866      });
     2867
     2868      ProtoBufSerializer serializer = new ProtoBufSerializer();
     2869      var v0 = test();
     2870
     2871      // seriealize C0, deserialize C0
     2872      serializer.Serialize(v0, tempFile);
     2873      var newV0 = (PersistenceTestC0)serializer.Deserialize(tempFile);
     2874      Assert.AreEqual(v0.value, newV0.value);
     2875      Assert.ReferenceEquals(newV0.neighbor, newV0);
     2876
     2877      // serialize C0, deserialize C1
     2878      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestC1));
     2879      var v1 = (PersistenceTestC1)serializer.Deserialize(tempFile);
     2880      Assert.AreEqual(v0.value, v1.value);
     2881      Assert.AreEqual(v1.neighborValue, v0.neighbor.value);
     2882    }
     2883
     2884    [StorableType("5AF91FB9-DB53-40BD-B961-A968D2F7CDE3")]
     2885    private class PersistenceTestSample4A0 {
     2886      [Storable]
     2887      public string Name;
     2888
     2889      [Storable]
     2890      public string Description;
     2891    }
     2892
     2893    [StorableType("5EDF9D5D-3B60-42E9-BA8D-7A007916D6AE")]
     2894    private class PersistenceTestSample4C0 : PersistenceTestSample4A0 {
     2895      [Storable]
     2896      public int p;
     2897    }
     2898
     2899    [StorableType("00000000-0000-0000-0000-0000000000D1")]
     2900    private class PersistenceTestSample4A1 {
     2901      [Storable]
     2902      public string Name;
     2903    }
     2904
     2905    [StorableType("A55EE4D0-EE2F-4DBD-834E-51200BFDBB9C")]
     2906    private class PersistenceTestSample4B : PersistenceTestSample4A1 {
     2907      [Storable(OldName = "base.Description")]
     2908      private string Description1 { set { Description = value; } }
     2909
     2910      [Storable(Name = "Description2")]
     2911      public string Description;
     2912    }
     2913
     2914    [StorableType("00000000-0000-0000-0000-0000000000E1")]
     2915    private class PersistenceTestSample4C1 : PersistenceTestSample4B {
     2916      [Storable]
     2917      public int p;
     2918    }
     2919
     2920    [StorableType("8CB577B8-C36B-4749-8CF4-33DE4D5AC4BF")]
     2921    class PersistenceTestSample4NewType0 : PersistenceTestSample4A1 {
     2922      [Storable]
     2923      public StringValue Description;
     2924    }
     2925
     2926    [StorableType("BCD9D34C-901C-44E6-B1FD-8F5E9E09D686")]
     2927    class AB {
     2928      [Storable(OldName = "5AF91FB9-DB53-40BD-B961-A968D2F7CDE3.Name", DefaultValue = "No name")]
     2929      public string Name;
     2930
     2931      [Storable(OldName = "A55EE4D0-EE2F-4DBD-834E-51200BFDBB9C.Description2", DefaultValue = "No description")]
     2932      public string Description;
     2933    }
     2934
     2935    [StorableType("00000000-0000-0000-0000-0000000000F1")]
     2936    class PersistenceTestSample4C2 : AB {
     2937      [Storable]
     2938      public int p;
     2939    }
     2940
     2941    [StorableType("00000000-0000-0000-0000-0000000001A1")]
     2942    class PersistenceTestSample4NewType1 : AB {
     2943      [Storable(OldName = "Description")]
     2944      private StringValue Description_Persistence_Setter {
     2945        set {
     2946          base.Description = value.Value;
     2947        }
     2948      }
     2949    }
     2950
     2951    [TestMethod]
     2952    [TestCategory("PersistenceNew.Conversion")]
     2953    [TestProperty("Time", "short")]
     2954    public void TestConversionSample4() {
     2955      var a0Type = typeof(PersistenceTestSample4A0);
     2956      var a0Guid = StorableTypeAttribute.GetStorableTypeAttribute(a0Type).Guid;
     2957      var c0Type = typeof(PersistenceTestSample4C0);
     2958      var c0Guid = StorableTypeAttribute.GetStorableTypeAttribute(c0Type).Guid;
     2959
     2960      var test = new Func<PersistenceTestSample4C0>(() => {
     2961        return new PersistenceTestSample4C0 {
     2962          Name = "test",
     2963          Description = "description",
     2964          p = 99
     2965        };
     2966      });
     2967
     2968      ProtoBufSerializer serializer = new ProtoBufSerializer();
     2969      var c0 = test();
     2970
     2971      // seriealize C0, deserialize C0
     2972      serializer.Serialize(c0, tempFile);
     2973      var newC0 = (PersistenceTestSample4C0)serializer.Deserialize(tempFile);
     2974      Assert.AreEqual(c0.Name, newC0.Name);
     2975      Assert.AreEqual(c0.Description, newC0.Description);
     2976      Assert.AreEqual(c0.p, newC0.p);
     2977
     2978      // serialize C0, deserialize C1
     2979      ReplaceTypeImplementation(c0Type, c0Guid, typeof(PersistenceTestSample4C1));
     2980      ReplaceTypeImplementation(a0Type, a0Guid, typeof(PersistenceTestSample4A1));
     2981      var c1 = (PersistenceTestSample4C1)serializer.Deserialize(tempFile);
     2982      Assert.AreEqual(c0.Name, c1.Name);
     2983      Assert.AreEqual(c0.Description, c1.Description);
     2984      Assert.AreEqual(c0.p, c1.p);
     2985
     2986      // serialize C1, deserialize C1
     2987      serializer.Serialize(c1, tempFile);
     2988      var newC1 = (PersistenceTestSample4C1)serializer.Deserialize(tempFile);
     2989      Assert.AreEqual(c1.Name, newC1.Name);
     2990      Assert.AreEqual(c1.Description, newC1.Description);
     2991      Assert.AreEqual(c1.p, newC1.p);
     2992
     2993      // serialize C1, deserialize C2
     2994      serializer.Serialize(c1, tempFile);
     2995      ReplaceTypeImplementation(c0Type, c0Guid, typeof(PersistenceTestSample4C2));
     2996      var c2 = (PersistenceTestSample4C2)serializer.Deserialize(tempFile);
     2997      Assert.AreEqual(c1.Name, c2.Name);
     2998      Assert.AreEqual(c1.Description, c2.Description);
     2999      Assert.AreEqual(c1.p, c2.p);
     3000
     3001      // serialize NewType0, deserialize NewType1
     3002      var newType0Type = typeof(PersistenceTestSample4NewType0);
     3003      var newType0Guid = StorableTypeAttribute.GetStorableTypeAttribute(newType0Type).Guid;
     3004
     3005      var newType0 = new PersistenceTestSample4NewType0 {
     3006        Name = "yeah",
     3007        Description = new StringValue("blubb")
     3008      };
     3009
     3010      serializer.Serialize(newType0, tempFile);
     3011      ReplaceTypeImplementation(newType0Type, newType0Guid, typeof(PersistenceTestSample4NewType1));
     3012      var newType1 = (PersistenceTestSample4NewType1)serializer.Deserialize(tempFile);
     3013      Assert.AreEqual(newType0.Name, newType1.Name);
     3014      Assert.AreEqual(newType0.Description.Value, newType1.Description);
     3015    }
    26723016    #endregion
    26733017  }
Note: See TracChangeset for help on using the changeset viewer.