public void RegisterConverterWithNonTypeConverter() { Assert.Throws <ArgumentException>(() => TypeConverterRegistry.RegisterConverter("System.DateTime", "System.DateTime")); }
/// <summary> /// Convert the value to the required <see cref="System.Type"/> (if necessary from a string). /// </summary> /// <param name="newValue">The proposed change value.</param> /// <param name="requiredType"> /// The <see cref="System.Type"/> we must convert to. /// </param> /// <param name="propertyName">Property name, used for error reporting purposes...</param> /// <exception cref="Oragon.Spring.Objects.ObjectsException"> /// If there is an internal error. /// </exception> /// <returns>The new value, possibly the result of type conversion.</returns> public static object ConvertValueIfNecessary(Type requiredType, object newValue, string propertyName) { if (newValue != null) { // if it is assignable, return the value right away if (IsAssignableFrom(newValue, requiredType)) { return(newValue); } // if required type is an array, convert all the elements if (requiredType != null && requiredType.IsArray) { // convert individual elements to array elements Type componentType = requiredType.GetElementType(); if (newValue is ICollection) { ICollection elements = (ICollection)newValue; return(ToArrayWithTypeConversion(componentType, elements, propertyName)); } else if (newValue is string) { if (requiredType.Equals(typeof(char[]))) { return(((string)newValue).ToCharArray()); } else { string[] elements = StringUtils.CommaDelimitedListToStringArray((string)newValue); return(ToArrayWithTypeConversion(componentType, elements, propertyName)); } } else if (!newValue.GetType().IsArray) { // A plain value: convert it to an array with a single component. Array result = Array.CreateInstance(componentType, 1); object val = ConvertValueIfNecessary(componentType, newValue, propertyName); result.SetValue(val, 0); return(result); } } // if required type is some ISet<T>, convert all the elements if (requiredType != null && requiredType.IsGenericType && TypeImplementsGenericInterface(requiredType, typeof(Oragon.Spring.Collections.Generic.ISet <>))) { // convert individual elements to array elements Type componentType = requiredType.GetGenericArguments()[0]; if (newValue is ICollection) { ICollection elements = (ICollection)newValue; return(ToTypedCollectionWithTypeConversion(typeof(Oragon.Spring.Collections.Generic.HashedSet <>), componentType, elements, propertyName)); } } // if required type is some IList<T>, convert all the elements if (requiredType != null && requiredType.IsGenericType && TypeImplementsGenericInterface(requiredType, typeof(IList <>))) { // convert individual elements to array elements Type componentType = requiredType.GetGenericArguments()[0]; if (newValue is ICollection) { ICollection elements = (ICollection)newValue; return(ToTypedCollectionWithTypeConversion(typeof(List <>), componentType, elements, propertyName)); } } // if required type is some IDictionary<K,V>, convert all the elements if (requiredType != null && requiredType.IsGenericType && TypeImplementsGenericInterface(requiredType, typeof(IDictionary <,>))) { Type[] typeParameters = requiredType.GetGenericArguments(); Type keyType = typeParameters[0]; Type valueType = typeParameters[1]; if (newValue is IDictionary) { IDictionary elements = (IDictionary)newValue; Type targetCollectionType = typeof(Dictionary <,>); Type collectionType = targetCollectionType.MakeGenericType(new Type[] { keyType, valueType }); object typedCollection = Activator.CreateInstance(collectionType); MethodInfo addMethod = collectionType.GetMethod("Add", new Type[] { keyType, valueType }); int i = 0; foreach (DictionaryEntry entry in elements) { string propertyExpr = BuildIndexedPropertyName(propertyName, i); object key = ConvertValueIfNecessary(keyType, entry.Key, propertyExpr + ".Key"); object value = ConvertValueIfNecessary(valueType, entry.Value, propertyExpr + ".Value"); addMethod.Invoke(typedCollection, new object[] { key, value }); i++; } return(typedCollection); } } // if required type is some IEnumerable<T>, convert all the elements if (requiredType != null && requiredType.IsGenericType && TypeImplementsGenericInterface(requiredType, typeof(IEnumerable <>))) { // convert individual elements to array elements Type componentType = requiredType.GetGenericArguments()[0]; if (newValue is ICollection) { ICollection elements = (ICollection)newValue; return(ToTypedCollectionWithTypeConversion(typeof(List <>), componentType, elements, propertyName)); } } // try to convert using type converter try { TypeConverter typeConverter = TypeConverterRegistry.GetConverter(requiredType); if (typeConverter != null && typeConverter.CanConvertFrom(newValue.GetType())) { try { newValue = typeConverter.ConvertFrom(newValue); } catch { if (newValue is string) { newValue = typeConverter.ConvertFromInvariantString((string)newValue); } } } else { typeConverter = TypeConverterRegistry.GetConverter(newValue.GetType()); if (typeConverter != null && typeConverter.CanConvertTo(requiredType)) { newValue = typeConverter.ConvertTo(newValue, requiredType); } else { // look if it's an enum if (requiredType != null && requiredType.IsEnum && (!(newValue is float) && (!(newValue is double)))) { // convert numeric value into enum's underlying type Type numericType = Enum.GetUnderlyingType(requiredType); newValue = Convert.ChangeType(newValue, numericType); if (Enum.IsDefined(requiredType, newValue)) { newValue = Enum.ToObject(requiredType, newValue); } else { throw new TypeMismatchException( CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); } } else if (newValue is IConvertible) { // last resort - try ChangeType newValue = Convert.ChangeType(newValue, requiredType); } else { throw new TypeMismatchException( CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); } } } } catch (Exception ex) { throw new TypeMismatchException( CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType, ex); } if (newValue == null && (requiredType == null || !Type.GetType("System.Nullable`1").Equals(requiredType.GetGenericTypeDefinition()))) { throw new TypeMismatchException( CreatePropertyChangeEventArgs(propertyName, null, newValue), requiredType); } } return(newValue); }
public void RegisterConverterWithNonResolvableType() { Assert.Throws <TypeLoadException>(() => TypeConverterRegistry.RegisterConverter("Systemm.DateTime", "System.ComponentModel.DateTimeConverter")); }
public void RegisterConverter() { TypeConverterRegistry.RegisterConverter("System.DateTime", "System.ComponentModel.DateTimeConverter"); }
public void GetSpringConverter() { TypeConverter converter = TypeConverterRegistry.GetConverter(typeof(string[])); Assert.IsTrue(converter is StringArrayConverter); }
public void GetInternalConverter() { TypeConverter converter = TypeConverterRegistry.GetConverter(typeof(int)); Assert.IsTrue(converter is Int32Converter); }
public void GetConverterForEnums() { TypeConverter converter = TypeConverterRegistry.GetConverter(typeof(DayOfWeek)); Assert.IsTrue(converter is EnumConverter); }