/// <summary> /// Applies mappings to the specified mapping configuration. /// </summary> /// <typeparam name="TSource">The source type.</typeparam> /// <typeparam name="TTarget">The target type.</typeparam> /// <param name="propertyFinder">An <see cref="IConventionEligiblePropertyFinder"/> with which to find eligible properties.</param> /// <param name="configuration">A mapping configuration to which mappings will be applied.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="propertyFinder"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> public void Apply <TSource, TTarget>(IConventionEligiblePropertyFinder propertyFinder, IMappingConfiguration <TSource, TTarget> configuration) { propertyFinder.ThrowIfNull("propertyFinder"); configuration.ThrowIfNull("configuration"); IEnumerable <PropertyInfo> sourceProperties = typeof(TSource) .GetAllPublicInstanceProperties() .ToArray(); IEnumerable <PropertyInfo> eligibleProperties = propertyFinder.GetEligibleProperties <TTarget>(); foreach (PropertyInfo eligibleProperty in eligibleProperties) { PropertyInfo tempEligibleProperty = eligibleProperty; PropertyInfo sourcePropertyInfo = sourceProperties.FindMatchingProperty(tempEligibleProperty.Name); if (sourcePropertyInfo == null) { continue; } TypeConverter targetConverter = TypeDescriptor.GetConverter(tempEligibleProperty.PropertyType); TypeConverter sourceConverter = TypeDescriptor.GetConverter(sourcePropertyInfo.PropertyType); // ReSharper disable ConditionIsAlwaysTrueOrFalse if (targetConverter != null && // ReSharper restore ConditionIsAlwaysTrueOrFalse !tempEligibleProperty.PropertyType.IsAssignableFrom(sourcePropertyInfo.PropertyType) && targetConverter.CanConvertFrom(sourcePropertyInfo.PropertyType)) { Func <TSource, object> @delegate = MappingConventionHelper.Instance.GetPropertyGetter <TSource>(sourcePropertyInfo).Compile(); configuration.Map(tempEligibleProperty.Name).From(source => targetConverter.ConvertFrom(@delegate(source))); } // ReSharper disable ConditionIsAlwaysTrueOrFalse else if (sourceConverter != null && // ReSharper restore ConditionIsAlwaysTrueOrFalse !tempEligibleProperty.PropertyType.IsAssignableFrom(sourcePropertyInfo.PropertyType) && sourceConverter.CanConvertTo(tempEligibleProperty.PropertyType)) { Func <TSource, object> @delegate = MappingConventionHelper.Instance.GetPropertyGetter <TSource>(sourcePropertyInfo).Compile(); configuration.Map(tempEligibleProperty.Name).From(source => sourceConverter.ConvertTo(@delegate(source), tempEligibleProperty.PropertyType)); } } }
/// <summary> /// Maps a property that appears to represent the same value in <typeparamref name="TSource"/> as <typeparamref name="TTarget"/>. /// </summary> /// <param name="configuration">A mapping configuration.</param> /// <param name="sourcePropertyInfo">A property of <typeparamref name="TSource"/>.</param> /// <param name="targetPropertyInfo">A property of <typeparamref name="TTarget"/>.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="sourcePropertyInfo"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="targetPropertyInfo"/> is null.</exception> public void MapLikeProperties <TSource, TTarget>(IMappingConfiguration <TSource, TTarget> configuration, PropertyInfo sourcePropertyInfo, PropertyInfo targetPropertyInfo) { configuration.ThrowIfNull("configuration"); sourcePropertyInfo.ThrowIfNull("sourcePropertyInfo"); targetPropertyInfo.ThrowIfNull("targetPropertyInfo"); Func <TSource, object> valueDelegate = GetPropertyGetter <TSource>(sourcePropertyInfo).Compile(); configuration.Map(targetPropertyInfo.Name).From(valueDelegate); }
/// <summary> /// Applies mappings to the specified mapping configuration. /// </summary> /// <typeparam name="TSource">The source type.</typeparam> /// <typeparam name="TTarget">The target type.</typeparam> /// <param name="propertyFinder">An <see cref="IConventionEligiblePropertyFinder"/> with which to find eligible properties.</param> /// <param name="configuration">A mapping configuration to which mappings will be applied.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="propertyFinder"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> public void Apply <TSource, TTarget>(IConventionEligiblePropertyFinder propertyFinder, IMappingConfiguration <TSource, TTarget> configuration) { propertyFinder.ThrowIfNull("propertyFinder"); configuration.ThrowIfNull("configuration"); IEnumerable <PropertyInfo> sourceProperties = typeof(TSource) .GetAllPublicInstanceProperties() .ToArray(); IEnumerable <PropertyInfo> eligibleProperties = propertyFinder.GetEligibleProperties <TTarget>(); foreach (PropertyInfo eligibleProperty in eligibleProperties) { PropertyInfo sourcePropertyInfo = sourceProperties.FindMatchingProperty(eligibleProperty.Name); if (sourcePropertyInfo == null || eligibleProperty.PropertyType.IsAssignableFrom(sourcePropertyInfo.PropertyType) || eligibleProperty.PropertyType.IsValueType) { continue; } object adapterFactory = _locator.Locate(sourcePropertyInfo.PropertyType, eligibleProperty.PropertyType); var mappingProvider = adapterFactory as IMappingProvider; if (mappingProvider != null) { try { mappingProvider.Validate(); } catch { continue; } } MethodInfo factoryCreateMethod = adapterFactory.GetType().GetMethod("Create"); ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "sourceInstance"); UnaryExpression methodCallExpression = Expression.Convert( Expression.Call( Expression.Constant(adapterFactory), factoryCreateMethod, Expression.Convert(parameterExpression, sourcePropertyInfo.PropertyType)), typeof(object)); Func <object, object> createAdapterDelegate = Expression.Lambda <Func <object, object> >(methodCallExpression, parameterExpression).Compile(); // ReSharper disable ConvertClosureToMethodGroup // Converting the lambda to a method group causes a runtime error Func <TSource, object> sourceGetterDelegate = MappingConventionHelper.Instance.GetNullSafePropertyEvaluation <TSource>(sourcePropertyInfo, source => createAdapterDelegate(source)); // ReSharper restore ConvertClosureToMethodGroup configuration.Map(eligibleProperty.Name).From(sourceGetterDelegate); } }
/// <summary> /// Applies mappings to the specified mapping configuration. /// </summary> /// <typeparam name="TSource">The source type.</typeparam> /// <typeparam name="TTarget">The target type.</typeparam> /// <param name="propertyFinder">An <see cref="IConventionEligiblePropertyFinder"/> with which to find eligible properties.</param> /// <param name="configuration">A mapper configuration to which mappings will be applied.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="propertyFinder"/> is null.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> public void Apply <TSource, TTarget>(IConventionEligiblePropertyFinder propertyFinder, IMappingConfiguration <TSource, TTarget> configuration) { propertyFinder.ThrowIfNull("propertyFinder"); configuration.ThrowIfNull("configuration"); IEnumerable <PropertyInfo> sourceProperties = typeof(TSource) .GetAllPublicInstanceProperties() .ToArray(); IEnumerable <PropertyInfo> eligibleProperties = propertyFinder.GetEligibleProperties <TTarget>(); foreach (PropertyInfo eligibleProperty in eligibleProperties) { PropertyInfo tempEligibleProperty = eligibleProperty; if (configuration.Mappings.Any(arg => arg.MemberName == tempEligibleProperty.Name)) { continue; } Type nullableTargetUnderlyingType = Nullable.GetUnderlyingType(tempEligibleProperty.PropertyType); if (nullableTargetUnderlyingType == null && !tempEligibleProperty.PropertyType.IsEnum) { continue; } if (nullableTargetUnderlyingType != null && !nullableTargetUnderlyingType.IsEnum) { continue; } PropertyInfo sourcePropertyInfo = sourceProperties.FindMatchingProperty(tempEligibleProperty.Name); Type nullableSourceUnderlyingType = sourcePropertyInfo != null?Nullable.GetUnderlyingType(sourcePropertyInfo.PropertyType) : null; if (sourcePropertyInfo == null || (!sourcePropertyInfo.PropertyType.IsEnum && (nullableSourceUnderlyingType == null || !nullableSourceUnderlyingType.IsEnum))) { continue; } Type type = typeof(DefaultEnumerationMapper <,>); Type defaultEnumerationMapperType = type.MakeGenericType(sourcePropertyInfo.PropertyType, tempEligibleProperty.PropertyType); try { object defaultEnumerationMapper = Activator.CreateInstance(defaultEnumerationMapperType, null); var mappingProvider = defaultEnumerationMapper as IMappingProvider; if (mappingProvider != null) { mappingProvider.Validate(); } MethodInfo getMappedValueMethod = defaultEnumerationMapper.GetType().GetMethod("GetMappedValue"); ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "sourceValue"); UnaryExpression methodCallExpression = Expression.Convert(Expression.Call( Expression.Constant(defaultEnumerationMapper), getMappedValueMethod, Expression.Convert(parameterExpression, sourcePropertyInfo.PropertyType)), typeof(object)); Func <object, object> getMappedValueFunc = Expression.Lambda <Func <object, object> >(methodCallExpression, parameterExpression).Compile(); Func <TSource, object> getterForSourceType = MappingConventionHelper.Instance.GetPropertyGetter <TSource>(sourcePropertyInfo).Compile(); configuration.Map(tempEligibleProperty.Name).From(source => getMappedValueFunc(getterForSourceType(source))); } catch { // Eat the exception because the determination of whether the enumeration is mappable is delegated to EnumerationMapper. // ReSharper disable RedundantJumpStatement continue; // ReSharper restore RedundantJumpStatement } } }
public void Configure(IMappingConfiguration config) { config.Map <Foo>(foo => foo.Name); }
public PropertyMapAction(IMappingConfiguration <TModel> mappingConfiguration, ParameterExpression parameter, Expression body) { mappingConfiguration.Map(Expression.Lambda <Func <TModel, TProperty> >(body, parameter)); }