Changeset 3031
- Timestamp:
- 03/15/10 12:25:55 (15 years ago)
- Location:
- trunk/sources/HeuristicLab.Persistence/3.3
- Files:
-
- 1 added
- 1 deleted
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableClassAttribute.cs
r3029 r3031 16 16 /// Specify how members are selected for serialization. 17 17 /// </summary> 18 public StorableClassType Type { get; set; }18 public StorableClassType Type { get; private set; } 19 19 20 20 /// <summary> … … 31 31 /// <see cref="StorableClassType.MarkedOnly"/>. 32 32 /// </summary> 33 public StorableClassAttribute() { 34 } 33 public StorableClassAttribute() { } 35 34 36 35 } -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs
r3016 r3031 19 19 /// </summary> 20 20 [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] 21 public sealed class StorableHookAttribute : Attribute { 22 23 private sealed class HookDesignator { 24 public Type Type { get; set; } 25 public HookType HookType { get; set; } 26 public HookDesignator() { } 27 public HookDesignator(Type type, HookType hookType) { 28 Type = type; 29 HookType = HookType; 30 } 31 } 21 public sealed class StorableHookAttribute : Attribute { 32 22 33 23 private readonly HookType hookType; … … 40 30 } 41 31 42 43 32 /// <summary> 44 33 /// Mark method as <c>StorableSerializer</c> hook to be run … … 48 37 public StorableHookAttribute(HookType hookType) { 49 38 this.hookType = hookType; 50 }51 52 private static readonly BindingFlags declaredInstanceMembers =53 BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly;54 55 private static readonly object[] emptyArgs = new object[] { };56 57 private static Dictionary<HookDesignator, List<MethodInfo>> hookCache =58 new Dictionary<HookDesignator, List<MethodInfo>>();59 60 61 /// <summary>62 /// Invoke <c>hookType</c> hook on <c>obj</c>.63 /// </summary>64 /// <param name="hookType">Type of the hook.</param>65 /// <param name="obj">The object.</param>66 public static void InvokeHook(HookType hookType, object obj) {67 if (obj == null)68 throw new ArgumentNullException("Cannot invoke hooks on null");69 foreach (MethodInfo mi in GetHooks(hookType, obj.GetType())) {70 mi.Invoke(obj, emptyArgs);71 }72 39 } 73 74 private static IEnumerable<MethodInfo> GetHooks(HookType hookType, Type type) {75 lock (hookCache) {76 List<MethodInfo> hooks;77 var designator = new HookDesignator(type, hookType);78 hookCache.TryGetValue(designator, out hooks);79 if (hooks != null)80 return hooks;81 hooks = new List<MethodInfo>(CollectHooks(hookType, type));82 hookCache.Add(designator, hooks);83 return hooks;84 }85 }86 87 private static IEnumerable<MethodInfo> CollectHooks(HookType hookType, Type type) {88 if (type.BaseType != null)89 foreach (var mi in CollectHooks(hookType, type.BaseType))90 yield return mi;91 foreach (MemberInfo memberInfo in type.GetMembers(declaredInstanceMembers)) {92 foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {93 if (hook != null && hook.HookType == hookType) {94 MethodInfo methodInfo = memberInfo as MethodInfo;95 if (memberInfo.MemberType != MemberTypes.Method || memberInfo == null)96 throw new ArgumentException("Storable hooks must be methods");97 yield return methodInfo;98 }99 }100 }101 }102 103 40 } 104 41 } -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableReflection.cs
r3029 r3031 17 17 BindingFlags.NonPublic | 18 18 BindingFlags.DeclaredOnly; 19 20 19 21 20 public static IEnumerable<StorableMemberInfo> GenerateStorableMembers(Type type, bool inherited) { … … 43 42 } 44 43 44 public static bool IsEmptyOrStorableType(Type type, bool recusrive) { 45 if (IsEmptyType(type, recusrive)) return true; 46 if (!HasStorableClassAttribute(type)) return false; 47 return !recusrive || type.BaseType == null || IsEmptyOrStorableType(type.BaseType, true); 48 } 49 50 public static IEnumerable<MethodInfo> CollectHooks(HookType hookType, Type type) { 51 if (type.BaseType != null) 52 foreach (var mi in CollectHooks(hookType, type.BaseType)) 53 yield return mi; 54 foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) { 55 foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) { 56 if (hook != null && hook.HookType == hookType) { 57 MethodInfo methodInfo = memberInfo as MethodInfo; 58 if (memberInfo.MemberType != MemberTypes.Method || memberInfo == null) 59 throw new ArgumentException("Storable hooks must be methods"); 60 yield return methodInfo; 61 } 62 } 63 } 64 } 65 66 #region [Storable] helpers 67 45 68 private static void AddMarkedMembers(Type type, List<StorableMemberInfo> storableMembers) { 46 69 foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) { … … 60 83 } 61 84 62 private static StorableClassAttribute GetStorableClassAttribute(Type type) {63 return (StorableClassAttribute)type64 .GetCustomAttributes(typeof(StorableClassAttribute), false)65 .SingleOrDefault();66 }67 85 68 86 private static IEnumerable<StorableMemberInfo> DisentangleNameMapping( … … 107 125 } 108 126 109 public static bool IsEmptyOrStorableType(Type type, bool recusrive) { 110 if (IsEmptyType(type, recusrive)) return true; 111 if (!HastStorableClassAttribute(type)) return false; 112 return !recusrive || type.BaseType == null || IsEmptyOrStorableType(type.BaseType, true); 127 #endregion 128 129 #region [StorableClass] helpers 130 131 private static StorableClassAttribute GetStorableClassAttribute(Type type) { 132 return (StorableClassAttribute)type 133 .GetCustomAttributes(typeof(StorableClassAttribute), false) 134 .SingleOrDefault(); 135 } 136 137 private static bool HasStorableClassAttribute(Type type) { 138 return type.GetCustomAttributes(typeof(StorableClassAttribute), false).Length > 0; 113 139 } 114 140 115 private static bool HastStorableClassAttribute(Type type) {116 return type.GetCustomAttributes(typeof(StorableClassAttribute), false).Length > 0; 117 }141 #endregion 142 143 #region other helpers 118 144 119 145 private static bool IsEmptyType(Type type, bool recursive) { … … 136 162 return pi.CanWrite; 137 163 } 164 165 #endregion 166 138 167 } 139 168 } -
trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
r3029 r3031 43 43 44 44 public IEnumerable<Tag> CreateMetaInfo(object o) { 45 StorableHookAttribute.InvokeHook(HookType.BeforeSerialization, o);45 InvokeHook(HookType.BeforeSerialization, o); 46 46 return new Tag[] { }; 47 47 } … … 79 79 } 80 80 } 81 StorableHookAttribute.InvokeHook(HookType.AfterDeserialization, instance);81 InvokeHook(HookType.AfterDeserialization, instance); 82 82 } 83 83 … … 89 89 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 90 90 91 private static readonly object[] emptyArgs = new object[] { }; 92 91 93 private sealed class TypeQuery { 92 94 public Type Type { get; private set; } … … 95 97 this.Type = type; 96 98 this.Inherited = inherited; 99 } 100 } 101 102 private sealed class HookDesignator { 103 public Type Type { get; set; } 104 public HookType HookType { get; set; } 105 public HookDesignator() { } 106 public HookDesignator(Type type, HookType hookType) { 107 Type = type; 108 HookType = HookType; 97 109 } 98 110 } … … 107 119 private Dictionary<Type, ConstructorInfo> constructorCache = 108 120 new Dictionary<Type, ConstructorInfo>(); 121 122 private Dictionary<HookDesignator, List<MethodInfo>> hookCache = 123 new Dictionary<HookDesignator, List<MethodInfo>>(); 109 124 110 125 #endregion … … 150 165 } 151 166 167 private void InvokeHook(HookType hookType, object obj) { 168 if (obj == null) 169 throw new ArgumentNullException("Cannot invoke hooks on null"); 170 foreach (MethodInfo mi in GetHooks(hookType, obj.GetType())) { 171 mi.Invoke(obj, emptyArgs); 172 } 173 } 174 175 private IEnumerable<MethodInfo> GetHooks(HookType hookType, Type type) { 176 lock (hookCache) { 177 List<MethodInfo> hooks; 178 var designator = new HookDesignator(type, hookType); 179 hookCache.TryGetValue(designator, out hooks); 180 if (hooks != null) 181 return hooks; 182 hooks = new List<MethodInfo>(StorableReflection.CollectHooks(hookType, type)); 183 hookCache.Add(designator, hooks); 184 return hooks; 185 } 186 } 187 152 188 #endregion 189 190 153 191 154 192 } -
trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
r3029 r3031 122 122 <Compile Include="Default\CompositeSerializers\Storable\StorableMemberInfo.cs" /> 123 123 <Compile Include="Default\CompositeSerializers\Storable\StorableClassType.cs" /> 124 <Compile Include=" Default\CompositeSerializers\Storable\DataMemberAccessor.cs" />124 <Compile Include="Core\DataMemberAccessor.cs" /> 125 125 <Compile Include="Default\CompositeSerializers\Storable\StorableClassAttribute.cs" /> 126 126 <Compile Include="Default\CompositeSerializers\Storable\StorableAttribute.cs" />
Note: See TracChangeset
for help on using the changeset viewer.