Ejemplo n.º 1
0
        public void UpdateRegisteredTypes()
        {
            foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (asm.IsDynamic)
                {
                    continue;
                }
                if (cachedAssemblies.Contains(asm.FullName))
                {
                    continue;
                }
                cachedAssemblies.Add(asm.FullName);

                foreach (var t in asm.GetTypes())
                {
                    if (typeof(ITransformer).IsAssignableFrom(t) && !t.IsAbstract)
                    {
                        var transformer = (ITransformer)Activator.CreateInstance(t);
                        RegisterTransformer(transformer);
                    }
                }

                foreach (var t in asm.GetTypes())
                {
                    if (StorableTypeAttribute.IsStorableType(t))
                    {
                        type2Guid.Add(t, StorableTypeAttribute.GetStorableTypeAttribute(t).Guid);
                        foreach (var guid in StorableTypeAttribute.GetStorableTypeAttribute(t).Guids)
                        {
                            if (guid2Type.ContainsKey(guid))
                            {
                                throw new PersistenceException($"The GUID {guid} is already used by type {guid2Type[guid]}.", t);
                            }
                            guid2Type.Add(guid, t);
                        }
                    }
                    else if (typeof(IStorableTypeMap).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
                    {
                        var knownTypeMap = (IStorableTypeMap)Activator.CreateInstance(t);
                        foreach (var tup in knownTypeMap.KnownStorableTypes)
                        {
                            RegisterType(tup.Item1, tup.Item2);
                        }
                    }
                }
            }
        }
        protected override void Populate(Box box, object value, Mapper mapper)
        {
            var kvpBox = new RepeatedValueBox();

            kvpBox.Kvps = new RepeatedKeyValuePairsBox();
            box.Values  = kvpBox;

            var keys   = kvpBox.Kvps.Keys;
            var values = kvpBox.Kvps.Values;

            foreach (DictionaryEntry item in (IDictionary)value)
            {
                if (mapper.CancellationToken.IsCancellationRequested)
                {
                    return;
                }
                keys.Add(mapper.GetBoxId(item.Key));
                values.Add(mapper.GetBoxId(item.Value));
            }

            var type         = value.GetType();
            var propertyInfo = type.GetProperty("Comparer");
            var comparer     = propertyInfo.GetValue(value);

            var comparerType = comparer.GetType();

            if (StorableTypeAttribute.IsStorableType(comparerType))
            {
                kvpBox.ComparerId = mapper.GetBoxId(comparer);
            }
            else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
            {
                throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
            }
            else
            {
                kvpBox.ComparerTypeId = mapper.GetTypeMetadataId(comparerType, transformer: null); // there is no transformer for the comparer type
            }
        }
Ejemplo n.º 3
0
        private static void ExecuteAfterDeserializationHooks(IEnumerator <object> e)
        {
            var emptyArgs = new object[0];

            while (e.MoveNext())
            {
                var obj = e.Current;

                if (obj == null || !StorableTypeAttribute.IsStorableType(obj.GetType()))
                {
                    continue;
                }

                var typeList = new LinkedList <Type>();
                for (var type = obj.GetType(); type != null; type = type.BaseType)
                {
                    typeList.AddFirst(type);
                }

                foreach (var type in typeList)
                {
                    if (!StorableTypeAttribute.IsStorableType(type))
                    {
                        continue;
                    }

                    var typeInfo = StaticCache.GetTypeInfo(type);
                    foreach (var hook in typeInfo.AfterDeserializationHooks)
                    {
                        try {
                            hook.Invoke(obj, emptyArgs);
                        } catch (TargetInvocationException t) {
                            throw t.InnerException;
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        protected override void Populate(Box box, object value, Mapper mapper)
        {
            box.Values = new RepeatedValueBox();
            var type         = value.GetType();
            var propertyInfo = type.GetProperty("Comparer");
            var comparer     = propertyInfo.GetValue(value);

            var comparerType = comparer.GetType();

            if (StorableTypeAttribute.IsStorableType(comparerType))
            {
                box.Values.ComparerId = mapper.GetBoxId(comparer);
            }
            else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
            {
                throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
            }
            else
            {
                box.Values.ComparerTypeId = mapper.GetTypeMetadataId(comparerType, transformer: null); // there is no transformer for the comparer type
            }
            AddRange((IEnumerable)value, box.Values, mapper);
        }
        protected override void Populate(Box box, object value, Mapper mapper)
        {
            if (mapper.CancellationToken.IsCancellationRequested)
            {
                return;
            }
            var emptyArgs = new object[0];
            var type      = value.GetType();

            // traverse type hierarchy

            var typeInfo = Mapper.StaticCache.GetTypeInfo(type);

            do
            {
                foreach (var hook in typeInfo.BeforeSerializationHooks)
                {
                    try {
                        hook.Invoke(value, emptyArgs);
                    } catch (TargetInvocationException t) {
                        throw t.InnerException;
                    }
                }

                type     = type.BaseType;
                typeInfo = Mapper.StaticCache.GetTypeInfo(type);
            } while (StorableTypeAttribute.IsStorableType(type) && !mapper.CancellationToken.IsCancellationRequested);


            var set = new HashSet <Tuple <Type, string> >();

            // traverse type hierarchy
            var membersBox = new StorableTypeMembersBox();

            box.Members = membersBox;

            type     = value.GetType();
            typeInfo = Mapper.StaticCache.GetTypeInfo(type);

            membersBox.StorableTypeMetadataId = mapper.GetStorableTypeMetadata(typeInfo.StorableTypeAttributeGuid);
            var layout = mapper.GetStorableTypeLayout(membersBox.StorableTypeMetadataId);

            while (StorableTypeAttribute.IsStorableType(type) && !mapper.CancellationToken.IsCancellationRequested)
            {
                foreach (var componentInfo in typeInfo.Fields)
                {
                    if (!layout.IsPopulated)
                    {
                        layout.MemberNames.Add(componentInfo.Name);
                    }
                    membersBox.ValueBoxId.Add(mapper.GetBoxId(componentInfo.MemberInfo.GetValue(value)));
                }

                foreach (var componentInfo in typeInfo.ReadableProperties)
                {
                    var declaringType = componentInfo.DeclaringType;

                    if (!set.Add(Tuple.Create(declaringType, componentInfo.Name)))
                    {
                        continue;
                    }

                    if (!layout.IsPopulated)
                    {
                        layout.MemberNames.Add(componentInfo.Name);
                    }
                    membersBox.ValueBoxId.Add(mapper.GetBoxId(componentInfo.MemberInfo.GetValue(value, null)));
                }

                layout.IsPopulated = true;

                // prepare for next iteration
                type = type.BaseType;
                if (StorableTypeAttribute.IsStorableType(type))
                {
                    typeInfo = Mapper.StaticCache.GetTypeInfo(type);
                    layout.ParentLayoutId = mapper.GetStorableTypeMetadata(typeInfo.StorableTypeAttributeGuid);
                    layout = mapper.GetStorableTypeLayout(layout.ParentLayoutId);
                }
            }
        }
 public override bool CanTransformType(Type type)
 {
     return(StorableTypeAttribute.IsStorableType(type) && !type.IsValueType && !type.IsEnum || // don't transform structs or enums
            type.BaseType != null && CanTransformType(type.BaseType));
 }
        public override void FillFromBox(object obj, Box box, Mapper mapper)
        {
            if (mapper.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            var dict    = new Dictionary <string, object>();
            var members = box.Members;
            var layout  = mapper.GetStorableTypeLayout(members.StorableTypeMetadataId);

            var valueIdx = 0;

            while (layout != null && !mapper.CancellationToken.IsCancellationRequested)
            {
                for (int j = 0; j < layout.MemberNames.Count; j++)
                {
                    string key   = mapper.GetComponentInfoKey(layout.TypeGuid, layout.MemberNames[j]);
                    object value = mapper.GetObject(members.ValueBoxId[valueIdx++]);
                    dict.Add(key, value);
                }
                layout = mapper.GetStorableTypeLayout(layout.ParentLayoutId);
            }

            var type      = mapper.StorableTypeMetadataToType(mapper.GetTypeMetadata(box.TypeMetadataId));
            var typeInfo  = Mapper.StaticCache.GetTypeInfo(type);
            var typeStack = new Stack <Tuple <Type, TypeInfo> >();

            do
            {
                typeInfo = Mapper.StaticCache.GetTypeInfo(type);
                typeStack.Push(Tuple.Create(type, typeInfo));
                type = type.BaseType;
            } while (StorableTypeAttribute.IsStorableType(type) && !mapper.CancellationToken.IsCancellationRequested);

            foreach (var frame in typeStack)
            {
                type     = frame.Item1;
                typeInfo = frame.Item2;

                // set stored or default values for all fields and properties
                foreach (var componentInfo in typeInfo.Fields)
                {
                    var attrib    = componentInfo.StorableAttribute;
                    var fieldInfo = componentInfo.MemberInfo;

                    if (dict.TryGetValue(componentInfo.FullName, out object value))
                    {
                        fieldInfo.SetValue(obj, value);
                    }
                    else if (attrib != null && attrib.DefaultValue != null)
                    {
                        fieldInfo.SetValue(obj, attrib.DefaultValue);
                    }
                }

                foreach (var componentInfo in typeInfo.WriteableProperties)
                {
                    var attrib       = componentInfo.StorableAttribute;
                    var propertyInfo = componentInfo.MemberInfo;

                    if (dict.TryGetValue(componentInfo.FullName, out object value))
                    {
                        propertyInfo.SetValue(obj, value, null);
                    }
                    else if (attrib != null && attrib.DefaultValue != null)
                    {
                        propertyInfo.SetValue(obj, attrib.DefaultValue, null);
                    }
                }
            }
        }