There are several ways of configuring a custom data source for a target member.

A source member:

Mapper.WhenMapping
    .From<ProductDto>()          // Apply to ProductDto mappings
    .To<Product>()               // Apply to Product creation, updates and merges
    .Map(ctx => ctx.Source.Spec) // ctx.Source is the ProductDto
    .To(p => p.Specification);   // p is the Product

// Or, more tersely:
Mapper.WhenMapping
    .From<ProductDto>().To<Product>()
    .Map(dto => dto.Spec, p => p.Specification);

A source expression (in this example, supplied inline):

// Source, target and mapping types are implicit from the mapping:
Mapper.Map(productDto).ToANew<Product>(cfg => cfg
    .Map(ctx => "$" + ctx.Source.Price) // ctx.Source is the ProductDto
    .To(p => p.Price));                 // p is the Product    

A constant value:

Mapper.WhenMapping
    .From<ProductDto>()      // Apply to ProductDto mappings
    .OnTo<Product>()         // Apply to Product merges only
    .Map("Company ABC")      // Always the same value
    .To(p => p.CompanyName); // p is the Product

// Or, more tersely:
Mapper.WhenMapping
    .From<ProductDto>().OnTo<Product>()
    .Map("Company ABC", p => p.CompanyName);

A value from an injected service:

// Retrieve an IDateTimeProvider instance from a configured
// service provider, and use its UtcNow value:
Mapper.WhenMapping
    .From<OrderDto>()        // Apply to OrderDto mappings
    .ToANew<Order>()         // Apply to Order creation
    .Map(ctx => ctx.GetService<IDateTimeProvider>().UtcNow)
    .To(o => o.DateCreated); // o is the Order

The result of a function call (inline):

Func<ProductDto, Product, string> companyNameFactory = 
    (dto, p) => dto.ManufaturerName + " Ltd";

// Source, target and mapping types are implicit from the mapping:
Mapper.Map(productDto).ToANew<Product>(cfg => cfg
    .Map(companyNameFactory)  // Map the factory function result
    .To(p => p.CompanyName)); // p is the Product

A sequence of data sources

// Map the Customer Home Address, Work Address
// then Address History to the CustomerViewModel
// AllAddresses property:
Mapper.WhenMapping
    .From<Customer>()                // Apply to Customer mappings
    .ToANew<CustomerViewModel>()     // Apply to CustomerViewModel creation
    .Map((c, vm) => new[] { c.HomeAddress })
        .Then.Map((c, vm) => new[] { c.WorkAddress })
        .Then.Map((c, vm) => c.AddressHistory)
    .To(vm => vm.AllAddresses);      // vm is the CustomerViewModel

Conditional Data Sources:

Any of these methods can be made conditional:

Mapper.WhenMapping
    .From<ProductDto>()                 // Apply to ProductDto mappings
    .ToANew<Product>()                  // Apply to Product creation only
    .If((dto, p) => dto.CompanyId == 0) // Apply only if CompanyId is 0
    .Map("No-one")                      // Always the same value
    .To(p => p.CompanyName);            // p is the Product
// Only include WorkAddress if it's different to HomeAddress:
Mapper.WhenMapping
    .From<Customer>()                // Apply to Customer mappings
    .ToANew<CustomerViewModel>()     // Apply to CustomerViewModel creation
    .Map((c, vm) => new[] { c.HomeAddress })
        .Then.If((c, vm) => c.WorkAddress != c.HomeAddress )
             .Map((c, vm) => new[] { c.WorkAddress })
        .Then.Map((c, vm) => c.AddressHistory)
    .To(vm => vm.AllAddresses);      // vm is the CustomerViewModel

And in an inline example:

Mapper.Map(productDto).ToANew<Product>(cfg => cfg
    .If((dto, p) => dto.CompanyId == 0) // Apply only if CompanyId is 0
    .Map("No-one")                      // Always the same value
    .To(p => p.CompanyName);            // p is the Product

Auto-Reversing Configured Data Sources

By default, configured data sources only apply in the direction configured - configuring ProductDto.Spec -> Product.Specification doesn't make Product.Specification map to ProductDto.Spec when the reverse mapping is performed.

To make every source- to target-member pairing you configure apply to mappings in either direction, use:

Mapper.WhenMapping.AutoReverseConfiguredDataSources();

To make every source- to target-member pairing you configure for a particular pair of Types apply to mappings in either direction, use:

Mapper.WhenMapping
    .From<Product>().To<ProductDto>()
    .AutoReverseConfiguredDataSources();

To make a source- to target-member pairing you configure apply to mappings in either direction, use:

Mapper.WhenMapping
    .From<Product>().To<ProductDto>()
    .Map(p => p.Specification, dto => dtp.Spec)
    .AndViceVersa();

Opting Out of Auto-Reversal

If you use the mapper-level AutoReverseConfiguredDataSources() to set the default behaviour, source- to target-member pairings you configure for a particular pair of Types can opt out using:

// Set the default behaviour:
Mapper.WhenMapping.AutoReverseConfiguredDataSources();

// Opt out for ProductDto -> Product:
Mapper.WhenMapping
    .From<Product>().To<ProductDto>()
    .DoNotAutoReverseConfiguredDataSources();

...and individual source- to target-member pairings can opt out with:

Mapper.WhenMapping
    .From<Product>().To<ProductDto>()
    .Map(p => p.Specification, dto => dtp.Spec)
    .ButNotViceVersa();

Mapping Nested Data Sources to the Target

To map a nested member to the target object, use, e.g:

// Source class - has a nested member 'Statistics':
class Video
{
    public string Title { get; set; }
    public int LengthInSeconds { get; set; }
    public VideoStatistics Statistics { get; set; }
}
class VideoStatistics
{
    public int ViewCount { get; set; }
}

// Target class:
class VideoDto
{
    public string Title { get; set; }
    public int LengthInSeconds { get; set; }
    public int ViewCount { get; set; }
}

Mapper.WhenMapping
    .From<Video>()      // Apply to Video mappings
    .To<VideoDto>()     // Apply to all VideoDto mappings
    .Map((v, dto) => v.Statistics)
    .ToTarget();        // The VideoDto is the target

In this example, the ToTarget() configuration causes Video.Statistics.ViewCount to be mapped to VideoDto.ViewCount. Video.Title is mapped to VideoDto.Title as expected.

Switching Data Sources

To switch a mapping data source to a different value, use, e.g:

class VideoLibrary
{
    public Dictionary<int, Video> VideosById { get; set; }
}

class VideoLibraryDto
{
    public IList<VideoDto> Videos { get; set; }
}

Mapper.WhenMapping
    .FromDictionariesWithValueType<Video>()
    .To<IList<VideoDto>>()
    .Map((d, l) => d.Values)
    .ToTargetInstead();

In this example, in any mapping where Dictionary<string, Video> is matched to an IList<VideoDto>, the Dictionary's Values collection is used as the source instead of the Dictionary.