.NET Core  

Fixing Ambiguous Method Calls in AutoMapper with DI in .NET

AutoMapper is a powerful object-to-object mapping library that simplifies the mapping between models and DTOs in .NET applications. However, when used with Dependency Injection (DI), developers occasionally face a common yet tricky issue: ambiguous method call errors.

In this article, we'll explore.

  • What causes ambiguous method calls in AutoMapper?
  • How does DI contribute to this error?
  • Practical scenarios that trigger ambiguity.
  • Effective solutions to fix the issue.
  • Best practices to avoid such problems.

The Problem: Ambiguous Method Calls

An ambiguous method call occurs when the compiler can’t decide between overloaded methods.

The call is ambiguous between the following methods or properties: 
'AutoMapper.IMapper.Map<TSource, TDestination>(TSource)' 
and 
'AutoMapper.IMapper.Map<TDestination>(object)'

This often happens when AutoMapper can’t resolve which overload to use based on the input parameters.

AutoMapper and Dependency Injection

In modern .NET apps, AutoMapper is typically registered and resolved via DI.

Registering AutoMapper in .NET Core / .NET 6+

services.AddAutoMapper(typeof(Startup));

Injecting AutoMapper

public class UserService
{
    private readonly IMapper _mapper;
    public UserService(IMapper mapper)
    {
        _mapper = mapper;
    }
    public UserDto GetUserDto(User user)
    {
        return _mapper.Map<UserDto>(user); // Might trigger ambiguity
    }
}

What Causes Ambiguity?

AutoMapper's Overloads

AutoMapper offers these two common overloads

TDestination Map<TSource, TDestination>(TSource source);
TDestination Map<TDestination>(object source);

If the compiler sees both as valid options, it throws an ambiguity error.

Example That Fails

object user = GetUser();
var dto = _mapper.Map<UserDto>(user); // Error: Ambiguous call

The compiler can’t decide between.

  • Map<object, UserDto>(user)
  • Map<UserDto>(object)

Solutions to Fix the Ambiguity

1. Specify Both Generic Types

Always prefer the Map<TSource, TDestination>() overload explicitly.

var dto = _mapper.Map<User, UserDto>((User)user);

2. Avoid Mapping from object or dynamic

Instead of

object user = GetUser();
_mapper.Map<UserDto>(user); // Ambiguous

Do this

var user = (User)GetUser();
_mapper.Map<UserDto>(user);

Or better,

User user = GetUser();
_mapper.Map<UserDto>(user);

3. Use Helper Extension for Explicit Mapping

public static class AutoMapperExtensions
{
    public static TDestination MapExplicit<TSource, TDestination>(this IMapper mapper, TSource source)
    {
        return mapper.Map<TSource, TDestination>(source);
    }
}

Usage

var dto = _mapper.MapExplicit<User, UserDto>(user);

4. Configure Mapping Profiles

public class UserProfile : Profile
{
    public UserProfile()
    {
        CreateMap<User, UserDto>();
    }
}

And register,

services.AddAutoMapper(typeof(UserProfile));

5. Update AutoMapper Package

Make sure you're using the latest version.

dotnet add package AutoMapper

Common Pitfalls

Pitfall Solution
Mapping from an object or a dynamic Use an explicit cast
Using var with ambiguous types Use strongly typed variables
Missing Profile mappings Always configure profiles
Outdated AutoMapper version Keep packages updated

Real-World API Example

[HttpPost]
public IActionResult CreateUser([FromBody] object model)
{
    var userDto = _mapper.Map<UserDto>(model); // Ambiguous
}

Solution

[HttpPost]
public IActionResult CreateUser([FromBody] User model)
{
    var userDto = _mapper.Map<UserDto>(model); // No ambiguity
}

Best Practices

  • Use itMap<TSource, TDestination>() whenever possible
  • Avoid using object or dynamic types
  • Configure your Profile mappings explicitly
  • Register AutoMapper properly via services.AddAutoMapper()
  • Use strongly typed models in services and controllers

GitHub Project URL

https://github.com/SardarMudassarAliKhan/AutoMapperwithDependencyInjection

Conclusion

Ambiguous method calls in AutoMapper with dependency injection are a result of compiler confusion over method overloads. The key is to be explicit with types, configure AutoMapper correctly, and avoid loosely typed mappings. With these strategies, you can confidently use AutoMapper in your .NET applications without ambiguity errors.