Reputation: 625
I have requirement to map two objects. The requirement is train reservation details which will have towardsjourney and return journey details.
public class ReservationSource
{
public string ReservationNumber{get;set;}
public TravelS towardsTravelS{get;set;}
public TravelS returnTravelS{get;set;}
}
This is the class which is in the ReservationSource
class which is to capture towards and return journey details.
public class TravelS
{
public string travelId{get;set;}
public ICollection<JourneyS> Journeys{get;set;}
}
Above is the reservation source object. This source needs a mapping to the destination object. Destination object is given below.
public class ReservationDestination
{
public string ReservationNumber{get;set;}
public TravelD towardsTravelD{get;set;}
public TravelD returnTravelD{get;set;}
}
public class TravelD
{
public string travelId{get;set;}
public ICollection<JourneyD> Journeys{get;set;}
}
public class JourneyD
{
public string JourneyId{get;set;}
}
public class JourneyS
{
public string JourneyId{get;set;}
}
This is my destination object . Here i want to map my source to destination. How do i define mapping config and map .
var config = new mappingConfiguration(cfg=>
{
cfg.CreateMap<ReservationSource,ReservationDestination>()
});
Imapper map = config.CreateMapper();
This part of code maps only the reservationNumber
to the destination object. Can someone help me to map all objects. That is towardsTravelS
to towardsTravelD
and returnTravelS
to returnTravelD
.
.net core version : 3.1
Upvotes: 2
Views: 3070
Reputation: 601
Add this in your services in startup :
it's reusable and cleaner
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
}
add these interface and class in your project
public interface IMapFrom<T>
{
void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
using AutoMapper;
using System;
using System.Linq;
using System.Reflection;
public class MappingProfile : Profile
{
public MappingProfile()
{
ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
}
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly.GetExportedTypes()
.Where(t => t.GetInterfaces()
.Any(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping")
?? type.GetInterface("IMapFrom`1").GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
and your source model be like this (map ReservationSource to ReservationSource):
public class ReservationSource : IMapFrom<ReservationSource>
{
public string Name { get; set; }
public string City { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<ReservationSource,ReservationDestination>()
.ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
.ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
}
}
Upvotes: 4
Reputation:
First of all you forgot to mention this but I assume there also is a class TravelS
that looks like this:
public class TravelS
{
public string TravelId { get; set; }
}
There are a few things missing in your configuration. At the moment AutoMapper doesn't know it has to map properties with different names (TowardsTravelS
=> TowardsTravelD
etc) so we have to define those aswell:
cfg.CreateMap<ReservationSource, ReservationDestination>()
.ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
.ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
Here we tell AutoMapper that these properties that have different names need to be mapped.
Secondly TravelS
and TravelD
are different classes so we need to configure them for mapping as well:
cfg.CreateMap<TravelS, TravelD>();
So we now have something like this:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ReservationSource, ReservationDestination>()
.ForMember(dest => dest.ReturnTravelD, opt => opt.MapFrom(src => src.ReturnTravelS))
.ForMember(dest => dest.TowardsTravelD, opt => opt.MapFrom(src => src.TowardsTravelS));
cfg.CreateMap<TravelS, TravelD>();
});
var mapper = config.CreateMapper();
var source = new ReservationSource
{
ReservationNumber = "9821",
ReturnTravelS = new TravelS
{
TravelId = "1"
},
TowardsTravelS = new TravelS
{
TravelId = "2"
}
};
var destination = mapper.Map<ReservationDestination>(source);
Console.WriteLine(JsonSerializer.Serialize(destination));
Output:
{"ReservationNumber":"9821","TowardsTravelD":{"TravelId":"2"},"ReturnTravelD":{"TravelId":"1"}}
Try it for yourself here: https://dotnetfiddle.net/FfccVR
Upvotes: 3