/// <inheritdoc/> protected override void UndoAction() { var flags = nonPublic ? BindingFlags.NonPublic | BindingFlags.Instance : BindingFlags.Public | BindingFlags.Instance; var propertyInfo = ContainerType.GetProperty(PropertyName, flags); var value = previousValue; previousValue = propertyInfo.GetValue(container); propertyInfo.SetValue(container, value); }
private void InitializeTypeInformation() { var typeInfo = ModelType.GetTypeInfo(); IsComplexType = !TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string)); IsNullableValueType = Nullable.GetUnderlyingType(ModelType) != null; IsReferenceType = !typeInfo.IsValueType; IsReferenceOrNullableType = !typeInfo.IsValueType || IsNullableValueType; UnderlyingOrModelType = Nullable.GetUnderlyingType(ModelType) ?? ModelType; IsFormFile = typeof(IFormFile).IsAssignableFrom(ModelType); IsSimpleType = IsSimple(ModelType); IsSystemObject = ModelType == typeof(object); var collectionType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(ICollection <>)); IsCollectionType = collectionType != null; if (ModelType == typeof(string) || !typeof(IEnumerable).IsAssignableFrom(ModelType)) { // Do nothing, not Enumerable. } else if (ModelType.IsArray) { IsEnumerableType = true; var elementType = ModelType.GetElementType(); PropertyInfo propertyInfo = ContainerType?.GetProperty(PropertyName); if (propertyInfo != null) { ElementType = new ProxyModelMetadata(propertyInfo, ProxyModelMetadataIdentity.ForProperty(elementType, propertyInfo.Name, ModelType), reflectedType: _reflectedType); } IsFormFile = typeof(IFormFile).IsAssignableFrom(elementType); } else { IsEnumerableType = true; var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(ModelType, typeof(IEnumerable <>)); var elementType = enumerableType?.GenericTypeArguments[0]; if (elementType != null) { IsFormFile = typeof(IFormFile).IsAssignableFrom(elementType); } if (elementType == null) { // ModelType implements IEnumerable but not IEnumerable<T>. elementType = typeof(object); } PropertyInfo propertyInfo = ContainerType?.GetProperty(PropertyName); if (propertyInfo != null) { ElementType = new ProxyModelMetadata(propertyInfo, ProxyModelMetadataIdentity.ForProperty(elementType, propertyInfo.Name, ModelType), reflectedType: _reflectedType); } } if (IsNullableValueType) { var elementType = Nullable.GetUnderlyingType(ModelType); PropertyInfo pInfo = ContainerType?.GetProperty(PropertyName); if (pInfo != null) { ElementType = new ProxyModelMetadata(pInfo, ProxyModelMetadataIdentity.ForProperty(elementType, pInfo.Name, ModelType), reflectedType: _reflectedType); } } if (IsComplexType && IsReferenceOrNullableType && (!IsEnumerableType && !IsCollectionType) && ModelType.Name != typeof(object).Name) { PropertyInfo[] properties = ModelType.GetProperties(); List <ProxyModelMetadata> metadataList = new List <ProxyModelMetadata>(); foreach (var prop in properties) { if (_reflectedType == null) { _reflectedType = prop.ReflectedType; } if (_reflectedType == prop.PropertyType) { // self reference loop continue; } if (ModelType == prop.PropertyType) { // Parent child ref - self reference loop continue; } metadataList.Add(new ProxyModelMetadata(prop, ProxyModelMetadataIdentity.ForProperty(prop.PropertyType, prop.Name, ModelType), reflectedType: _reflectedType)); } Properties = metadataList; } }