/// <summary> /// Allows configuration of custom mappings at runtime through the specified mapper configuration. /// </summary> /// <param name="configuration">A mapper configuration.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> protected override void ConfigureMapper(MapperConfiguration <TSource, TTarget> configuration) { configuration.ThrowIfNull("configuration"); _conventions = GetConventions(); ApplyConventions(configuration); ConfigureCustomMapping(configuration); }
/// <summary> /// Initializes a new instance of the <see cref="Mapper{TSource,TTarget}"/> class. /// </summary> /// <param name="mapperFlags">Mapper flags.</param> /// <param name="configuration">The mapper configuration to use for mappings.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> protected Mapper(MapperFlags mapperFlags, MapperConfiguration <TSource, TTarget> configuration) { configuration.ThrowIfNull("configuration"); _mapperFlags = mapperFlags; _configuration = configuration; _mapMethodDelegate = new Lazy <Action <TSource, TTarget> >( () => { ConfigureMapper(); return(_generator.GenerateMappingMethod(_configuration)); }); }
/// <summary> /// Generates a delegate that invokes the mappings and actions contained in the specified mapper configuration. /// </summary> /// <typeparam name="TSource">The source type.</typeparam> /// <typeparam name="TTarget">The target type.</typeparam> /// <param name="configuration">A mapper configuration.</param> /// <returns>A delegate that invokes the mappings and actions contained in <paramref name="configuration"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="configuration"/> is null.</exception> public Action <TSource, TTarget> GenerateMappingMethod <TSource, TTarget>(MapperConfiguration <TSource, TTarget> configuration) { configuration.ThrowIfNull("configuration"); configuration.Validate(); Type funcArgumentType = typeof(Func <TSource, object>[]); Type actionArgumentType = typeof(Action <TTarget, TSource>[]); Type sourceType = typeof(TSource); Type targetType = typeof(TTarget); Type[] methodArguments = { funcArgumentType, actionArgumentType, sourceType, targetType }; string methodName = String.Format("MappingMethod_{0}_to_{1}_{2:N}", sourceType.FullName, targetType.FullName, Guid.NewGuid()); var mappingMethod = new DynamicMethod(methodName, typeof(void), methodArguments, targetType.Module); ILGenerator ilGenerator = mappingMethod.GetILGenerator(); Action <TTarget, TSource>[] mapActions = configuration.Actions .Where(arg => arg.MapDelegate != null) .Select(arg => arg.MapDelegate) .ToArray(); // Only map members that have no corresponding action, or that have a corresponding action with a non-null delegate // This query ignores mappings that have a corresponding action with a null delegate MemberMapping <TSource>[] mappings = (from m in configuration.Mappings join a in configuration.Actions on m.MemberName equals a.MemberName into ma from a in ma.DefaultIfEmpty() where a == null || a.MapDelegate != null select m).ToArray(); EmitMemberMappings(mappings, targetType, ilGenerator); EmitMemberMapActions(mapActions, ilGenerator); ilGenerator.Emit(OpCodes.Ret); var methodDelegate = (MappingMethodDelegate <TSource, TTarget>)mappingMethod.CreateDelegate(typeof(MappingMethodDelegate <TSource, TTarget>)); Func <TSource, object>[] mapFuncs = mappings .Where(arg => arg.ValueDelegate != null) .Select(arg => arg.ValueDelegate) .ToArray(); return((source, target) => methodDelegate(mapFuncs, mapActions, source, target)); }