private static bool TryCreateDictionaryMap <T>(FallbackStrategy emptyValueStrategy, out IMap map) { // We should be able to parse anything that implements IEnumerable<KeyValuePair<TKey, TValue>> if (!typeof(T).ImplementsGenericInterface(typeof(IEnumerable <>), out Type keyValuePairType)) { map = null; return(false); } if (!keyValuePairType.IsGenericType || keyValuePairType.GetGenericTypeDefinition() != typeof(KeyValuePair <,>)) { map = null; return(false); } Type[] arguments = keyValuePairType.GenericTypeArguments; Type keyType = arguments[0]; Type valueType = arguments[1]; MethodInfo method = TryCreateGenericDictionaryMapMethod.MakeGenericMethod(keyType, valueType); var parameters = new object[] { typeof(T), emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (result) { map = (IMap)parameters[2]; return(true); } map = null; return(false); }
public static bool AutoMapClass <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> classMap) { Type type = typeof(T); if (type.GetTypeInfo().IsInterface) { classMap = null; return(false); } var map = new ExcelClassMap <T>(); IEnumerable <MemberInfo> properties = type.GetRuntimeProperties().Where(p => p.CanWrite); IEnumerable <MemberInfo> fields = type.GetRuntimeFields().Where(f => f.IsPublic); foreach (MemberInfo member in properties.Concat(fields)) { Type memberType = member.MemberType(); MethodInfo method = MappingMethod.MakeGenericMethod(memberType); var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (!result) { classMap = null; return(false); } map.Mappings.Add((ExcelPropertyMap)parameters[2]); } classMap = map; return(true); }
public static bool AutoMapEnumerable <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out EnumerableExcelPropertyMap <T> map) { Type rawType = member.MemberType(); TypeInfo rawTypeInfo = rawType.GetTypeInfo(); if (!member.AutoMap(emptyValueStrategy, out SingleExcelPropertyMap <T> elementMapping)) { map = null; return(false); } if (rawType.IsArray) { map = new ArrayPropertyMap <T>(member, elementMapping); return(true); } else if (rawTypeInfo.IsInterface) { if (rawTypeInfo.IsAssignableFrom(typeof(List <T>).GetTypeInfo())) { map = new InterfaceAssignableFromListPropertyMap <T>(member, elementMapping); return(true); } } else if (rawType.ImplementsInterface(typeof(ICollection <T>))) { map = new ConcreteICollectionPropertyMap <T>(rawType, member, elementMapping); return(true); } map = null; return(false); }
private static bool InferMapping <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out ExcelPropertyMap mapping) { if (member.AutoMap(emptyValueStrategy, out SingleExcelPropertyMap <T> singleMapping)) { mapping = singleMapping; return(true); } if (member.MemberType().GetElementTypeOrEnumerableType(out Type elementType)) { MethodInfo method = AutoMapEnumerableMethod.MakeGenericMethod(elementType); var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (result) { mapping = (ExcelPropertyMap)parameters[2]; return(true); } } if (member.AutoMapObject(emptyValueStrategy, out ObjectExcelPropertyMap <T> objectMapping)) { mapping = objectMapping; return(true); } mapping = null; return(false); }
private static bool InferMapping <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out ExcelPropertyMap map) { // First, check if this is a well-known type (e.g. string/int). // This is a simple conversion from the cell's value to the type. if (TryMapPrimitive(member, emptyValueStrategy, out SingleExcelPropertyMap <T> singleMap)) { map = singleMap; return(true); } // Secondly, check if this is a collection (e.g. array, list). // This requires converting each value to the element type of the collection. if (TryMapEnumerable(member, emptyValueStrategy, out ExcelPropertyMap multiMap)) { map = multiMap; return(true); } // Thirdly, check if this is an object. // This requires converting each member and setting it on the object. if (TryMapObject(member, emptyValueStrategy, out ObjectExcelPropertyMap <T> objectMap)) { map = objectMap; return(true); } map = null; return(false); }
public SerializationContext(FallbackStrategy fallbackStrategy, IEnumerable <Type> types) : this(fallbackStrategy) { foreach (var type in types) { Register(type); } }
public void Ctor_EmptyValueStrategy(FallbackStrategy emptyValueStrategy) { var map = new TestClassMap(emptyValueStrategy); Assert.Equal(emptyValueStrategy, map.EmptyValueStrategy); Assert.Equal(typeof(Helpers.TestClass), map.Type); }
/// <summary> /// Constructs a new class map for the given type using the given default strategy to use /// when the value of a cell is empty. /// </summary> /// <param name="emptyValueStrategy">The default strategy to use when the value of a cell is empty.</param> public ExcelClassMap(FallbackStrategy emptyValueStrategy) : this() { if (!Enum.IsDefined(typeof(FallbackStrategy), emptyValueStrategy)) { throw new ArgumentException($"Invalid value \"{emptyValueStrategy}\".", nameof(emptyValueStrategy)); } EmptyValueStrategy = emptyValueStrategy; }
private InProvider BuildProvider(FallbackStrategy fallbackStrategy = null, string fallbackLanguage = null) { return(new InBuilder() .AddJsonFile(TestUtils.DataJsonEnFile1, TestUtils.DataJsonEnLanguageCode, true) .AddJsonFile(TestUtils.DataJsonViFile1, TestUtils.DataJsonViLanguageCode) .SetFallbackStrategy(fallbackStrategy ?? FallbackStrategy.DefaultFallbackStrategy) .SetFallbackLanguage(fallbackLanguage ?? "en") .Build()); }
internal static bool TryCreateObjectMap <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> mapping) { if (!TryCreateClassMap(emptyValueStrategy, out ExcelClassMap <T> excelClassMap)) { mapping = null; return(false); } mapping = excelClassMap; return(true); }
public static bool AutoMapObject <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out ObjectExcelPropertyMap <T> mapping) { if (!AutoMapClass(emptyValueStrategy, out ExcelClassMap <T> excelClassMap)) { mapping = null; return(false); } mapping = new ObjectExcelPropertyMap <T>(member, excelClassMap); return(true); }
public static bool TryMapPrimitive <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out SingleExcelPropertyMap <T> map) { if (!GetWellKnownMapper(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback)) { map = null; return(false); } map = new SingleExcelPropertyMap <T>(member) .WithCellValueMappers(mapper) .WithEmptyFallbackItem(emptyFallback) .WithInvalidFallbackItem(invalidFallback); return(true); }
public static bool AutoMap <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out SingleExcelPropertyMap <T> mapping) { if (!typeof(T).AutoMap(emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback)) { mapping = null; return(false); } mapping = new SingleExcelPropertyMap <T>(member) .WithCellValueMappers(mapper) .WithEmptyFallbackItem(emptyFallback) .WithInvalidFallbackItem(invalidFallback); return(true); }
/// <summary> /// Creates a class map for the given type using the given strategy. /// </summary> /// <param name="emptyValueStrategy">The default strategy to use when the value of a cell is empty.</param> /// <param name="classMap">The class map for the given type.</param> /// <returns>True if the class map could be created, else false.</returns> public static bool TryCreateClassMap <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> classMap) { if (!Enum.IsDefined(typeof(FallbackStrategy), emptyValueStrategy)) { throw new ArgumentException($"Invalid value \"{emptyValueStrategy}\".", nameof(emptyValueStrategy)); } Type type = typeof(T); if (type.GetTypeInfo().IsInterface) { classMap = null; return(false); } var map = new ExcelClassMap <T>(emptyValueStrategy); IEnumerable <MemberInfo> properties = type.GetRuntimeProperties().Where(p => p.CanWrite && p.SetMethod.IsPublic && !p.SetMethod.IsStatic); IEnumerable <MemberInfo> fields = type.GetRuntimeFields().Where(f => f.IsPublic && !f.IsStatic); foreach (MemberInfo member in properties.Concat(fields)) { // Ignore this property/field. if (Attribute.IsDefined(member, typeof(ExcelIgnoreAttribute))) { continue; } // Infer the mapping for each member (property/field) belonging to the type. Type memberType = member.MemberType(); MethodInfo method = TryCreateMemberMapMethod.MakeGenericMethod(memberType); if (memberType == type) { throw new ExcelMappingException($"Cannot map recursive property \"{member.Name}\" of type {memberType}. Consider applying the ExcelIgnore attribute."); } var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (!result) { classMap = null; return(false); } // Get the out parameter representing the property map for the member. map.Properties.Add(new ExcelPropertyMap(member, (IMap)parameters[2])); } classMap = map; return(true); }
internal static bool TryCreatePrimitivePipeline <T>(FallbackStrategy emptyValueStrategy, out ValuePipeline <T> pipeline) { if (!TryGetWellKnownMap(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback)) { pipeline = null; return(false); } pipeline = new ValuePipeline <T>(); pipeline.AddCellValueMapper(mapper); pipeline.EmptyFallback = emptyFallback; pipeline.InvalidFallback = invalidFallback; return(true); }
public void TryCreateClassMap_ValidType_ReturnsTrue(FallbackStrategy emptyValueStrategy) { Assert.True(AutoMapper.TryCreateClassMap <TestClass>(emptyValueStrategy, out ExcelClassMap <TestClass> classMap)); Assert.Equal(emptyValueStrategy, classMap.EmptyValueStrategy); Assert.Equal(typeof(TestClass), classMap.Type); Assert.Equal(5, classMap.Properties.Count); IEnumerable <string> members = classMap.Properties.Select(m => m.Member.Name); Assert.Contains("_inheritedField", members); Assert.Contains("_field", members); Assert.Contains("InheritedProperty", members); Assert.Contains("Property", members); Assert.Contains("PrivateGetProperty", members); }
internal static bool TryCreatePrimitiveMap <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out OneToOneMap <T> map) { if (!TryGetWellKnownMap(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback)) { map = null; return(false); } ISingleCellValueReader defaultReader = GetDefaultSingleCellValueReader(member); map = new OneToOneMap <T>(defaultReader) .WithCellValueMappers(mapper) .WithEmptyFallbackItem(emptyFallback) .WithInvalidFallbackItem(invalidFallback); return(true); }
internal static bool TryAutoMap <T>(FallbackStrategy emptyValueStrategy, out IMap result) { // First see if we can create a dictionary map of this type. if (TryCreateDictionaryMap <T>(emptyValueStrategy, out IMap dictionaryMap)) { result = dictionaryMap; return(true); } else if (TryCreateClassMap(emptyValueStrategy, out ExcelClassMap <T> classMap)) { result = classMap; return(true); } result = null; return(false); }
private static bool TryCreateEnumerableMap(MemberInfo member, FallbackStrategy emptyValueStrategy, out IMap map) { if (!member.MemberType().GetElementTypeOrEnumerableType(out Type elementType)) { map = null; return(false); } MethodInfo method = TryCreateGenericEnumerableMapMethod.MakeGenericMethod(elementType); var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (result) { map = (IMap)parameters[2]; return(true); } map = null; return(false); }
public static bool TryMapGenericEnumerable <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out EnumerableExcelPropertyMap <T> map) { Type rawType = member.MemberType(); TypeInfo rawTypeInfo = rawType.GetTypeInfo(); // First, get the mapper for the element. This is used to convert individual values // to be added to/included in the collection. if (!TryMapPrimitive(member, emptyValueStrategy, out SingleExcelPropertyMap <T> elementMapping)) { map = null; return(false); } // Secondly, find the right way of adding the converted value to the collection. if (rawType.IsArray) { // Add values using the arrray indexer. map = new ArrayPropertyMap <T>(member, elementMapping); return(true); } else if (rawTypeInfo.IsInterface) { // Add values by creating a list and assigning to the property. if (rawTypeInfo.IsAssignableFrom(typeof(List <T>).GetTypeInfo())) { map = new InterfaceAssignableFromListPropertyMap <T>(member, elementMapping); return(true); } } else if (rawType.ImplementsInterface(typeof(ICollection <T>))) { // Add values using the ICollection<T>.Add method. map = new ConcreteICollectionPropertyMap <T>(rawType, member, elementMapping); return(true); } map = null; return(false); }
private static bool TryCreateMemberMap <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out IMap map) { // First, check if this is a well-known type (e.g. string/int). // This is a simple conversion from the cell's value to the type. if (TryCreatePrimitiveMap(member, emptyValueStrategy, out OneToOneMap <T> singleMap)) { map = singleMap; return(true); } // Secondly, check if this is a dictionary. // This requires converting each value to the value type of the collection. if (TryCreateDictionaryMap <T>(emptyValueStrategy, out IMap dictionaryMap)) { map = dictionaryMap; return(true); } // Thirdly, check if this is a collection (e.g. array, list). // This requires converting each value to the element type of the collection. if (TryCreateEnumerableMap(member, emptyValueStrategy, out IMap multiMap)) { map = multiMap; return(true); } // Fourthly, check if this is an object. // This requires converting each member and setting it on the object. if (TryCreateObjectMap(emptyValueStrategy, out ExcelClassMap <T> objectMap)) { map = objectMap; return(true); } map = null; return(false); }
public SerializationContext(FallbackStrategy fallbackStrategy) : this() { this.fallbackStrategy = fallbackStrategy; }
public SerializationContext() { this.fallbackStrategy = FallbackStrategy.DynamicObject; this.serializerObjectFactory = new SerializerObjectFactory(); this.objectWrapperFactory = new ObjectWrapperFactory(this); }
private static bool AutoMap(this Type memberType, FallbackStrategy emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback) { Type type = memberType.GetNullableTypeOrThis(out bool isNullable); Type[] interfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray(); IFallbackItem ReconcileFallback(FallbackStrategy strategyToPursue, bool empty) { // Empty nullable values should be set to null. if (empty && isNullable) { return(new FixedValueFallback(null)); } else if (strategyToPursue == FallbackStrategy.SetToDefaultValue || emptyValueStrategy == FallbackStrategy.SetToDefaultValue) { return(new FixedValueFallback(type.DefaultValue())); } else { Debug.Assert(emptyValueStrategy == FallbackStrategy.ThrowIfPrimitive); // The user specified that we should set to the default value if it was empty. return(new ThrowFallback()); } } if (type == typeof(DateTime)) { mapper = new DateTimeMapper(); emptyFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false); } else if (type == typeof(bool)) { mapper = new BoolMapper(); emptyFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false); } else if (type.GetTypeInfo().IsEnum) { mapper = new EnumMapper(type); emptyFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false); } else if (type == typeof(string) || type == typeof(object) || type == typeof(IConvertible)) { mapper = new StringMapper(); emptyFallback = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: false); } else if (type == typeof(Uri)) { mapper = new UriMapper(); emptyFallback = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false); } else if (interfaces.Any(t => t == typeof(IConvertible))) { mapper = new ChangeTypeMapper(type); emptyFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true); invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false); } else { mapper = null; emptyFallback = null; invalidFallback = null; return(false); } return(true); }
internal static bool TryCreateGenericEnumerableMap <TElement>(MemberInfo member, FallbackStrategy emptyValueStrategy, out ManyToOneEnumerableMap <TElement> map) { // First, get the pipeline for the element. This is used to convert individual values // to be added to/included in the collection. if (!TryCreatePrimitivePipeline <TElement>(emptyValueStrategy, out ValuePipeline <TElement> elementMapping)) { map = null; return(false); } // Secondly, find the right way of adding the converted value to the collection. if (!TryGetCreateElementsFactory <TElement>(member.MemberType(), out CreateElementsFactory <TElement> factory)) { map = null; return(false); } // Default to splitting. var defaultNameReader = GetDefaultSingleCellValueReader(member); var defaultReader = new CharSplitCellValueReader(defaultNameReader); map = new ManyToOneEnumerableMap <TElement>(defaultReader, elementMapping, factory); return(true); }
public void Ctor_InvalidEmptyValueStrategy_ThrowsArgumentException(FallbackStrategy emptyValueStrategy) { Assert.Throws <ArgumentException>("emptyValueStrategy", () => new TestClassMap(emptyValueStrategy)); }
internal static bool TryCreateGenericDictionaryMap <TKey, TValue>(Type memberType, FallbackStrategy emptyValueStrategy, out ManyToOneDictionaryMap <TValue> map) { if (!TryCreatePrimitivePipeline <TValue>(emptyValueStrategy, out ValuePipeline <TValue> valuePipeline)) { map = null; return(false); } if (!TryGetCreateDictionaryFactory <TKey, TValue>(memberType, out CreateDictionaryFactory <TValue> factory)) { map = null; return(false); } // Default to all columns. var defaultReader = new AllColumnNamesValueReader(); map = new ManyToOneDictionaryMap <TValue>(defaultReader, valuePipeline, factory); return(true); }
public InBuilder SetFallbackStrategy(FallbackStrategy fallbackStrategy) { this.FallbackStrategy = fallbackStrategy; return(this); }
public void TryCreateClassMap_InvalidFallbackStrategy_ThrowsArgumentException(FallbackStrategy emptyValueStrategy) { Assert.Throws <ArgumentException>("emptyValueStrategy", () => AutoMapper.TryCreateClassMap <IConvertible>(emptyValueStrategy, out _)); }
public SerializationContext(FallbackStrategy fallbackStrategy, IEnumerable<Type> types) : this(fallbackStrategy) { foreach (var type in types) Register(type); }
public TestClassMap(FallbackStrategy emptyValueStrategy) : base(emptyValueStrategy) { }