'Automapper. Map if source member is null

I have two classes and map one to other with Automapper. For instance:

public class Source 
{
    // IdName is a simple class containing two fields: Id (int) and Name (string)
    public IdName Type { get; set; } 

    public int TypeId {get; set; }

    // another members
}

public class Destination
{
    // IdNameDest is a simple class such as IdName
    public IdNameDest Type { get; set; } 

    // another members
}

Then I use Automapper to map Source to Destination:

cfg.CreateMap<Source, Destination>();

It works properly but sometimes member Type in class Source becomes null. In these cases I would like to map member Type in class Destination from TypeId property. That's what I want in a nutshel:

if Source.Type != null 
then map Destination.Type from it
else map it as 
    Destination.Type = new IdNameDest { Id = Source.Id }

Is it possible with AutoMapper?



Solution 1:[1]

You can use the .ForMember() method while declaring the mapping. Like so :

cfg.CreateMap<Source, Destination>()
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Type != null ? src.Type : new IdNameDest { Id = src.Id }));

Solution 2:[2]

While LeeeonTMs answer works fine AutoMapper provides a specialised mechanism to substitute null values. It "allows you to supply an alternate value for a destination member if the source value is null anywhere along the member chain" (taken from the AutoMapper manual).

Example:

cfg.CreateMap<Source, Destination>()
    .ForMember(dest => dest.Value, opt => opt.NullSubstitute(new IdNameDest { Id = src.Id }));

Solution 3:[3]

With C# 6.0, the null-coalescing operator can be used.

cfg.CreateMap<Source, Destination>()
   .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.Type ?? new IdNameDest { Id = src.Id }));

Solution 4:[4]

I managed to resolve it with Mapping Resolvers

public class SomeResolver : IValueResolver<Soruce, Dest, Guid>
{
    public Guid Resolve(Source source, Dest destination, Guid, destMember, ResolutionContext context)
    {
       
        destination.Value= source.Value!=null ? source.Value:0;

        return destination.MainGuid = Guid.NewGuid();
    }
}

and then on mapping configuraiton

       CreateMap<BioTimeEmployeeSummaryDTO, BioTimeEmployeeAttendanceSummary>()
         
            
            .ForMember(dest => dest.MainGuid, opt => opt.MapFrom<YourResolverClass>())

            .ReverseMap();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jan
Solution 3 tuncay alt?npulluk
Solution 4 Eyayu Tefera