Example #1
0
        /// <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 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>
        /// 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 && tempEligibleProperty.PropertyType.IsAssignableFrom(sourcePropertyInfo.PropertyType))
                {
                    MappingConventionHelper.Instance.MapLikeProperties(configuration, sourcePropertyInfo, tempEligibleProperty);
                }
            }
        }
Example #5
0
        /// <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
                }
            }
        }