Exemplo n.º 1
0
        /// <summary>
        /// Visits the specified object.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <param name="descriptor">The descriptor.</param>
        /// <exception cref="ArgumentNullException">
        /// obj
        /// or
        /// descriptor
        /// </exception>
        /// <exception cref="ArgumentException">Descriptor [{0}] type doesn't correspond to object type [{1}].ToFormat(descriptor.Type, obj.GetType())</exception>
        protected void Visit(object obj, ITypeDescriptor descriptor)
        {
            if (obj == null)
            {
                VisitNull();
                return;
            }

            var objectType = obj.GetType();

            if (descriptor == null || descriptor.Type != objectType)
            {
                descriptor = TypeDescriptorFactory.Find(objectType);
            }

            if (descriptor is NullableDescriptor)
            {
                descriptor = TypeDescriptorFactory.Find(((NullableDescriptor)descriptor).UnderlyingType);
            }

            context.Instance   = obj;
            context.Descriptor = (ObjectDescriptor)descriptor;

            switch (descriptor.Category)
            {
            case DescriptorCategory.Primitive:
                VisitPrimitive(obj, (PrimitiveDescriptor)descriptor);
                break;

            default:
                // Note that the behaviour is slightly different if a type has a custom visitor or not.
                // If it has a custom visitor, it will visit the object even if the object has been already visited
                // otherwise it will use CanVisit() on this instance. The CanVisit() is tracking a list of
                // visited objects and it will not revisit the object.
                IDataCustomVisitor customVisitor;
                if (!mapTypeToCustomVisitors.TryGetValue(objectType, out customVisitor) && CustomVisitors.Count > 0)
                {
                    for (var i = CustomVisitors.Count - 1; i >= 0; i--)
                    {
                        var dataCustomVisitor = CustomVisitors[i];
                        if (dataCustomVisitor.CanVisit(objectType))
                        {
                            customVisitor = dataCustomVisitor;
                            mapTypeToCustomVisitors.Add(objectType, dataCustomVisitor);
                            break;
                        }
                    }
                }

                if (customVisitor != null)
                {
                    customVisitor.Visit(ref context);
                }
                else if (CanVisit(obj))
                {
                    VisitObject(obj, context.Descriptor, true);
                }
                break;
            }
        }
Exemplo n.º 2
0
 /// <inheritdoc />
 public virtual void VisitArray(Array array, ArrayDescriptor descriptor)
 {
     for (var i = 0; i < array.Length; i++)
     {
         var value = array.GetValue(i);
         CurrentPath.Push(descriptor, i);
         VisitArrayItem(array, descriptor, i, value, TypeDescriptorFactory.Find(value?.GetType() ?? descriptor.ElementType));
         CurrentPath.Pop();
     }
 }
Exemplo n.º 3
0
        /// <inheritdoc />
        public virtual void VisitSet(IEnumerable set, SetDescriptor descriptor)
        {
            // Make a copy in case VisitCollectionItem mutates something
            IEnumerator enumerator = set.GetEnumerator();

            while (enumerator.MoveNext())
            {
                object item = enumerator.Current;
                CurrentPath.Push(descriptor, item);
                VisitSetItem(set, descriptor, item, TypeDescriptorFactory.Find(item?.GetType() ?? descriptor.ElementType));
                CurrentPath.Pop();
            }
        }
Exemplo n.º 4
0
        /// <inheritdoc />
        public virtual void VisitCollection(IEnumerable collection, CollectionDescriptor descriptor)
        {
            var i = 0;

            // Make a copy in case VisitCollectionItem mutates something
            var items = collection.Cast <object>().ToList();

            foreach (var item in items)
            {
                CurrentPath.Push(descriptor, i);
                VisitCollectionItem(collection, descriptor, i, item, TypeDescriptorFactory.Find(item?.GetType() ?? descriptor.ElementType));
                CurrentPath.Pop();
                i++;
            }
        }
Exemplo n.º 5
0
        /// <inheritdoc />
        public virtual void VisitDictionary(object dictionary, DictionaryDescriptor descriptor)
        {
            // Make a copy in case VisitCollectionItem mutates something
            var items = descriptor.GetEnumerator(dictionary).ToList();

            foreach (var keyValue in items)
            {
                var key             = keyValue.Key;
                var keyDescriptor   = TypeDescriptorFactory.Find(keyValue.Key?.GetType() ?? descriptor.KeyType);
                var value           = keyValue.Value;
                var valueDescriptor = TypeDescriptorFactory.Find(keyValue.Value?.GetType() ?? descriptor.ValueType);

                CurrentPath.Push(descriptor, key);
                VisitDictionaryKeyValue(dictionary, descriptor, key, keyDescriptor, value, valueDescriptor);
                CurrentPath.Pop();
            }
        }
Exemplo n.º 6
0
        /// <inheritdoc />
        public virtual void VisitCollection(IEnumerable collection, CollectionDescriptor descriptor)
        {
            if (descriptor.Category == DescriptorCategory.Set)
            {
                throw new ArgumentException("Shouldn't call VisitCollection() to visit a set");
            }
            var i = 0;

            // Make a copy in case VisitCollectionItem mutates something
            var items = collection.Cast <object>().ToList();

            foreach (var item in items)
            {
                CurrentPath.Push(descriptor, i);
                VisitCollectionItem(collection, descriptor, i, item, TypeDescriptorFactory.Find(item?.GetType() ?? descriptor.ElementType));
                CurrentPath.Pop();
                i++;
            }
        }