Open Closed

AutoMapper not used in IdentityUserAppService after upgrading to ABP v10.1.1 (Mapperly mapping attempted) #10513


User avatar
0
sserestyen created

Hi,

After upgrading our project from ABP Framework v9.3.7 to v10.1.1, we kept AutoMapper as our object mapping solution instead of the new default Mapperly.

We configured AutoMapper in our application module as follows:

public class MyApplicationModule : AbpModule
{
}

Inside ConfigureServices:

Configure<AbpAutoMapperOptions>(options =>
{
    options.AddMaps<MyApplicationModule>();
});

Our AutoMapper profiles are discovered correctly, and mapping works as expected in our custom application services.

For example, mapping works without issues in:

public class MyCustomAppService : MyProjectAppService, IMyCustomAppService

However, when using the same mappings inside a service that derives from the ABP identity service:

public class MyProjectIdentityUserAppService : IdentityUserAppService

we receive an exception during execution. The exception indicates that the framework is attempting to resolve a mapping using Mapperly, even though AutoMapper is configured and working elsewhere in the application.

This suggests that the IdentityUserAppService (or the underlying object mapper context) is still trying to use Mapperly instead of AutoMapper after the upgrade.

Observed behavior:

  • AutoMapper is configured and working correctly in custom application services.
  • The same mappings fail when used in a service derived from IdentityUserAppService.
  • The thrown exception suggests that the framework attempts to resolve mappings through Mapperly.

Expected behavior: Since AutoMapper is configured in the application module and works in other services, we would expect the same AutoMapper configuration to be used when extending IdentityUserAppService.

Is there an additional configuration required in ABP v10.1.1 to ensure that IdentityUserAppService uses AutoMapper instead of Mapperly? Or is there a recommended approach for overriding the object mapper context in services derived from IdentityUserAppService?

Any guidance on the correct configuration for using AutoMapper in this scenario would be appreciated.

Thanks.

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

5 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    However, when using the same mappings inside a service that derives from the ABP identity service:

    Can you share some demo code and exception logs?

    Thanks.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    sserestyen created

    Hi,

    I have the log only at the moment. See below:

    Thanks.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Thanks. Can you also share some code of the mapper and your custom app service?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    sserestyen created

    Hi,

    please use below code in a new project.

    using System;
    
    using System.Linq;
    
    using System.Threading.Tasks;
     
    using Microsoft.AspNetCore.Identity;
    
    using Microsoft.Extensions.Options;
     
    using Volo.Abp.Application.Dtos;
    
    using Volo.Abp.Authorization.Permissions;
    
    using Volo.Abp.Caching;
    
    using Volo.Abp.EventBus.Distributed;
    
    using Volo.Abp.Identity;
    
    using Volo.Abp.Threading;
     
    namespace Test.Identity;
     
    public class MyIdentityUserAppService : IdentityUserAppService
    
    {
    
        public MyIdentityUserAppService(
    
                IdentityUserManager userManager,
    
                IIdentityUserRepository userRepository,
    
                IIdentityRoleRepository roleRepository,
    
                IOrganizationUnitRepository organizationUnitRepository,
    
                IIdentityClaimTypeRepository claimTypeRepository,
    
                IdentityProTwoFactorManager twoFactorManager,
    
                IOptions<IdentityOptions> identityOptions,
    
                IDistributedEventBus eventBus,
    
                IOptions<AbpIdentityOptions> abpIdentityOptions,
    
                IPermissionChecker permissionChecker,
    
                IDistributedCache<IdentityUserDownloadTokenCacheItem, string> userDownloadTokenCache,
    
                IDistributedCache<ImportInvalidUsersCacheItem, string> importInvalidUsersCache,
    
                IdentitySessionManager sessionManager,
    
                IdentityUserTwoFactorChecker userTwoFactorChecker,
    
                ICancellationTokenProvider cancellationTokenProvider)
    
                : base(
    
                    userManager,
    
                    userRepository,
    
                    roleRepository,
    
                    organizationUnitRepository,
    
                    claimTypeRepository,
    
                    twoFactorManager,
    
                    identityOptions,
    
                    eventBus,
    
                    abpIdentityOptions,
    
                    permissionChecker,
    
                    userDownloadTokenCache,
    
                    importInvalidUsersCache,
    
                    sessionManager,
    
                    userTwoFactorChecker,
    
                    cancellationTokenProvider)
    
        {
    
        }
     
        public async Task<PagedResultDto<LookupDto<Guid>>> GetDummy(LookupRequestDto input)
    
        {
    
            var users = await UserRepository.GetListAsync();
     
            var items = users.Select(ObjectMapper.Map<IdentityUser, LookupDto<Guid>>)
    
                    .OrderBy(u => u.DisplayName)
    
                    .ToList();
     
            return new PagedResultDto<LookupDto<Guid>>(items.Count, items);
    
        }
    
    }
     
    

    See below AutoMapper configuration below:

    CreateMap<IdentityUser, LookupDto<Guid>>()
                .ForMember(
                    d => d.DisplayName,
                    m => m.MapFrom(s =>
                        s.Name + " " +
                        s.Surname + " (" +
                        s.UserName + ")"));
     
    

    Thanks, S.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The issue is caused by a breaking change in ABP v10. IdentityUserAppService sets ObjectMapperContext = typeof(AbpIdentityApplicationModule), which forces the inherited ObjectMapper to use Mapperly (the new default in v10). Your AutoMapper profile is not visible in that context.

    Here are two ways to fix it:


    Option 1: Keep Using AutoMapper

    Inject AutoMapper's IMapper directly into your service and use it instead of the inherited ObjectMapper:

    public class MyIdentityUserAppService : IdentityUserAppService
    {
        private readonly IMapper _mapper;
    
        public MyIdentityUserAppService(
            IdentityUserManager userManager,
            IIdentityUserRepository userRepository,
            IIdentityRoleRepository roleRepository,
            IOptions<IdentityOptions> identityOptions,
            IPermissionChecker permissionChecker,
            IMapper mapper
        ) : base(userManager, userRepository, roleRepository, identityOptions, permissionChecker)
        {
            _mapper = mapper;
        }
    
        public LookupDto<Guid> GetDummy(IdentityUser user)
        {
            return _mapper.Map<LookupDto<Guid>>(user);
        }
    }
    

    Your existing AutoMapper profile (CreateMap<IdentityUser, LookupDto<Guid>>) works as-is. No other changes needed.


    Option 2: Migrate to Mapperly (Recommended)

    Create a Mapperly mapper class. ABP will automatically discover and register it:

    public class IdentityUserToLookupDtoMapper : MapperBase<IdentityUser, LookupDto<Guid>>
    {
        public override LookupDto<Guid> Map(IdentityUser source)
        {
            return new LookupDto<Guid>
            {
                Id = source.Id,
                DisplayName = $"{source.Name} {source.Surname} ({source.UserName})"
            };
        }
    }
    

    Then remove the CreateMap<IdentityUser, LookupDto<Guid>>() entry from your AutoMapper profile.

    For more details, see: https://abp.io/docs/latest/framework/infrastructure/object-to-object-mapping#mapperly-integration

    Thanks.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 24, 2026, 12:09
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.