tutorial mvc initialize inicializar example createmap c# asp.net-mvc-4 automapper

c# - mvc - Pasar objetos al mapeo de AutoMapper



mapper initialize (4)

AutoMapper maneja este escenario de par clave-valor fuera de la caja.

Mapper.CreateMap<Source, Dest>() .ForMember(d => d.Foo, opt => opt.ResolveUsing(res => res.Context.Options.Items["Foo"]));

Luego en el tiempo de ejecución:

Mapper.Map<Source, Dest>(src, opt => opt.Items["Foo"] = "Bar");

Un poco detallado para profundizar en los elementos de contexto, pero hay que ir.

Estoy trabajando con AutoMapper y algunos de los valores de la entidad a la que se asigna son variables en mi método actual. He intentado buscarlo en Google, pero sin éxito. ¿Puedo pasar un conjunto de pares de KeyValue o un objeto o algo a mi asignación para que use esos valores?

Muestra de modificación de post mapeo

//comment variable is a Comment class instance var imageComment = AutoMapper.Mapper.Map<Data.ImageComment>(comment); //I want to pass in imageId so I dont have to manually add it after the mapping imageComment.ImageId = imageId;


Los objetos se pueden pasar al resolutor con la opción Diccionario de Items . La API estándar para hacer esto es bastante detallada (como se ve en la respuesta aceptada) pero se puede simplificar muy bien usando algunos métodos de extensión:

/// <summary> /// Map using a resolve function that is passed the Items dictionary from mapping context /// </summary> public static void ResolveWithContext<TSource, TDest, TMember, TResult>( this IMemberConfigurationExpression<TSource, TDest, TMember> memberOptions, Func<TSource, IDictionary<string, object>, TDest, TMember, TResult> resolver ) { memberOptions.ResolveUsing((src, dst, member, context) => resolver.Invoke(src, context.Items, dst, member)); } public static TDest MapWithContext<TSource, TDest>(this IMapper mapper, TSource source, IDictionary<string, object> context, Action<IMappingOperationOptions<TSource, TDest>> optAction = null) { return mapper.Map<TSource, TDest>(source, opts => { foreach(var kv in context) opts.Items.Add(kv); optAction?.Invoke(opts); }); }

Que se puede usar así:

// Define mapping configuration Mapper.CreateMap<Comment, ImageComment>() .ForMember( d => d.ImageId, opt => opt.ResolveWithContext(src, items, dst, member) => items["ImageId"]) ); // Execute mapping var context = new Dictionary<string, object> { { "ImageId", ImageId } }; return mapper.MapWithContext<TSource, TDest>(source, context);

Si tiene un objeto que comúnmente necesita pasar a los solucionadores de asignadores (por ejemplo, el usuario actual), puede ir un paso más allá y definir extensiones más especializadas:

public static readonly string USER_CONTEXT_KEY = "USER"; /// <summary> /// Map using a resolve function that is passed a user from the /// Items dictionary in the mapping context /// </summary> public static void ResolveWithUser<TSource, TDest, TMember, TResult>( this IMemberConfigurationExpression<TSource, TDest, TMember> memberOptions, Func<TSource, User, TResult> resolver ) { memberOptions.ResolveWithContext((src, items, dst, member) => resolver.Invoke(src, items[USER_CONTEXT_KEY] as User)); } /// <summary> /// Execute a mapping from the source object to a new destination /// object, with the provided user in the context. /// </summary> public static TDest MapForUser<TSource, TDest>( this IMapper mapper, TSource source, User user, Action<IMappingOperationOptions<TSource, TDest>> optAction = null ) { var context = new Dictionary<string, object> { { USER_CONTEXT_KEY, user } }; return mapper.MapWithContext(source, context, optAction); }

Que se puede utilizar como:

// Create mapping configuration Mapper.CreateMap<Source, Dest>() .ForMember(d => d.Foo, opt => opt.ResolveWithUser((src, user) src.Foo(user)); // Execute mapping return mapper.MapWithUser(source, user);


Para Automapper 6.0.2:

Perfil:

public class CoreProfile : Profile { public CoreProfile() { CreateMap<Source, Dest>() .ForMember(d => d.Foo, opt => opt.ResolveUsing( (src, dst, arg3, context) => context.Options.Items["Foo"] ) ); } }

Cartografía:

var result = Mapper.Map<PlanResult>(aa, opt => { opt.Items["Foo"] = 2; opt.Items["OtherFoo"] = 1000; });


Supongamos que tienes estos dos objetos:

public class ObjectA { public string Property1 { get; set; } public int Property2 { get; set; } } public class ObjectB { public string Property1 { get; set; } public int Property2 { get; set; } }

Y desea copiar un objeto existente de tipo ObjectA en un nuevo objeto de tipo ObjectB , utilizando AutoMapper tiene que hacer esto:

var objectA = new ObjectA { Property1 = "Hello, World!", Property2 = 1 } var objectB = new ObjectB(); // Copy data from a to b AutoMapper.Mapper .CreateMap<ObjectA, ObjectB>() .BeforeMap((source, dest) => { dest.ImageId = imageId }); AutoMapper.Mapper.Map(objectA, objectB); // source, destination; // Or: var objectB = AutoMapper.Mapper.Map<ObjectB>(objectA);