private bool FillComplexProperty(ComplexProperty property, InternalTypeInfo typeInfo, object value) { if (property == null) { return(false); } // Parsing properties ParseProperties(property, typeInfo, value); return(true); }
private static Property CreateSimpleProperty(string name, InternalTypeInfo typeInfo, object value) { if (!typeInfo.IsSimple) { return(null); } var result = new SimpleProperty(name, typeInfo.Type) { Value = value }; return(result); }
private void ParseCollectionItems(CollectionProperty property, InternalTypeInfo info, object value) { property.ElementType = info.ElementType; var collection = (IEnumerable)value; foreach (var item in collection) { var itemProperty = CreateProperty(null, item); property.Items.Add(itemProperty); } }
private void ParseProperties(ComplexProperty property, InternalTypeInfo typeInfo, object value) { var propertyInfos = _propertyProvider.GetProperties(typeInfo); foreach (var propertyInfo in propertyInfos) { var subValue = propertyInfo.GetValue(value, _emptyObjectArray); var subProperty = CreateProperty(propertyInfo.Name, subValue); property.Properties.Add(subProperty); } }
private bool FillDictionaryProperty(DictionaryProperty property, InternalTypeInfo info, object value) { if (property == null) { return(false); } // Properties ParseProperties(property, info, value); // Items ParseDictionaryItems(property, info, value); return(true); }
private bool FillCollectionProperty(CollectionProperty property, InternalTypeInfo info, object value) { if (property == null) { return(false); } // Parsing properties ParseProperties(property, info, value); // Parse Items ParseCollectionItems(property, info, value); return(true); }
private void ParseDictionaryItems(DictionaryProperty property, InternalTypeInfo info, object value) { property.KeyType = info.KeyType; property.ValueType = info.ElementType; var dictionary = (IDictionary)value; foreach (DictionaryEntry entry in dictionary) { var keyProperty = CreateProperty(null, entry.Key); var valueProperty = CreateProperty(null, entry.Value); property.Items.Add(new KeyValueItem(keyProperty, valueProperty)); } }
/// <summary> /// Fills the <see cref="InternalTypeInfo.KeyType" /> and <see cref="InternalTypeInfo.ElementType" /> properties /// to target <see paramref="target" /> from <paramref name="source" />. /// </summary> /// <returns><c>TRUE</c> if the key and value definition was found, otherwise <c>FALSE</c></returns> private static bool FillKeyAndElementType(InternalTypeInfo source, Type target) { var targetInfo = target.GetTypeInfo(); if (!targetInfo.IsGenericType) { return(false); } var arguments = target.GetGenericArguments(); if (source.IsDictionary) { // in Dictionary there are keys and values source.KeyType = arguments[0]; source.ElementType = arguments[1]; } else { // In Collection there are only items source.ElementType = arguments[0]; } return(arguments.Length > 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); }
private bool FillSingleDimensionalArrayProperty(SingleDimensionalArrayProperty property, InternalTypeInfo info, object value) { if (property == null) { return(false); } property.ElementType = info.ElementType; var analyzer = new ArrayAnalyzer(value); // Dimensionen var dimensionInfo = analyzer.ArrayInfo.DimensionInfos[0]; property.LowerBound = dimensionInfo.LowerBound; // Items foreach (object item in analyzer.GetValues()) { var itemProperty = CreateProperty(null, item); property.Items.Add(itemProperty); } return(true); }
private bool FillMultiDimensionalArrayProperty(MultiDimensionalArrayProperty property, InternalTypeInfo info, object value) { if (property == null) { return(false); } property.ElementType = info.ElementType; var analyzer = new ArrayAnalyzer(value); // DimensionInfos property.DimensionInfos = analyzer.ArrayInfo.DimensionInfos; // Items foreach (var indexSet in analyzer.GetIndexes()) { var subValue = ((Array)value).GetValue(indexSet); var itemProperty = CreateProperty(null, subValue); property.Items.Add(new MultiDimensionalArrayItem(indexSet, itemProperty)); } return(true); }
private static ReferenceTargetProperty CreateReferenceTargetInstance(string name, InternalTypeInfo typeInfo) { // Is it array? if (typeInfo.IsArray) { if (typeInfo.ArrayDimensionCount < 2) { return(new SingleDimensionalArrayProperty(name, typeInfo.Type)); } // MultiD-Array return(new MultiDimensionalArrayProperty(name, typeInfo.Type)); } if (typeInfo.IsDictionary) { return(new DictionaryProperty(name, typeInfo.Type)); } if (typeInfo.IsCollection) { return(new CollectionProperty(name, typeInfo.Type)); } if (typeInfo.IsEnumerable) { return(new CollectionProperty(name, typeInfo.Type)); } // If nothing was recognized, a complex type will be created return(new ComplexProperty(name, typeInfo.Type)); }
/// <summary> /// </summary> /// <param name="type"></param> /// <returns></returns> public static InternalTypeInfo GetTypeInfo(Type type) { // check if Info is in cache var typeInfo = Cache.TryGetTypeInfo(type); if (typeInfo == null) { // no info in cache yet typeInfo = new InternalTypeInfo { Type = type, IsSimple = Tools.IsSimple(type) }; // check if array of byte if (type == typeof(byte[])) { typeInfo.ElementType = typeof(byte); } // Only not simple types can be Collections if (!typeInfo.IsSimple) { // check if it is an Array typeInfo.IsArray = Tools.IsArray(type); if (typeInfo.IsArray) { // Array? What is its element type? if (type.HasElementType) { typeInfo.ElementType = type.GetElementType(); } // How many dimensions typeInfo.ArrayDimensionCount = type.GetArrayRank(); } else { // It is not Array, maybe Enumerable? typeInfo.IsEnumerable = Tools.IsEnumerable(type); if (typeInfo.IsEnumerable) { // it is Enumerable maybe Collection? typeInfo.IsCollection = Tools.IsCollection(type); if (typeInfo.IsCollection) { // Sure it is a Collection, but maybe Dictionary also? typeInfo.IsDictionary = Tools.IsDictionary(type); // Fill its key and value types, if the listing is generic bool elementTypeDefinitionFound; var examinedType = type; do { elementTypeDefinitionFound = FillKeyAndElementType(typeInfo, examinedType); examinedType = examinedType.GetTypeInfo().BaseType; // until key and element definition was found, or the base typ is an object } while (!elementTypeDefinitionFound && (examinedType != null) && (examinedType != typeof(object))); } } } } if (!Cache.Contains(typeInfo)) { Cache.Add(typeInfo); } } return(typeInfo); }