Пример #1
0
        /// <summary>
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns>NullProperty if the value is null</returns>
        public Property CreateProperty(string name, object value)
        {
            if (value == null)
            {
                return(new NullProperty(name));
            }

            // If value type is recognized, it will be taken from typeinfo cache
            var typeInfo = InternalTypeInfo.GetTypeInfo(value);

            // Is it simple type
            var property = CreateSimpleProperty(name, typeInfo, value);

            if (property != null)
            {
                return(property);
            }

            // From now it can only be an instance of ReferenceTargetProperty
            var referenceTarget = CreateReferenceTargetInstance(name, typeInfo);

            // Search in Cache
            ReferenceTargetProperty cachedTarget;

            if (_propertyCache.TryGetValue(value, out cachedTarget))
            {
                // Value was already referenced
                // Its reference will be used
                cachedTarget.Reference.Count++;
                referenceTarget.MakeFlatCopyFrom(cachedTarget);
                return(referenceTarget);
            }

            // Target was not found in cache
            // it must be created

            // Adding property to cache
            referenceTarget.Reference = new ReferenceInfo
            {
                Id = _currentReferenceId++
            };
            _propertyCache.Add(value, referenceTarget);

            // Parsing the property
            var handled = FillSingleDimensionalArrayProperty(referenceTarget as SingleDimensionalArrayProperty, typeInfo,
                                                             value);

            handled = handled ||
                      FillMultiDimensionalArrayProperty(referenceTarget as MultiDimensionalArrayProperty, typeInfo,
                                                        value);
            handled = handled || FillDictionaryProperty(referenceTarget as DictionaryProperty, typeInfo, value);
            handled = handled || FillCollectionProperty(referenceTarget as CollectionProperty, typeInfo, value);
            handled = handled || FillComplexProperty(referenceTarget as ComplexProperty, typeInfo, value);

            if (!handled)
            {
                throw new InvalidOperationException($"Property cannot be filled. Property: {referenceTarget}");
            }

            return(referenceTarget);
        }