我目前正在开发一个项目,其中使用 AutoMapper 在应用程序的不同层之间映射对象。在我的 AutoMapper 配置文件之一中,我需要在执行映射之前调用异步方法来检索一些附加数据。但是,AutoMapper 配置文件似乎并不直接支持异步方法。
这是我想要实现的目标的简化示例:
public class Profile : AutoMapper.Profile
{
public Profile(ISequence sequence)
{
CreateMap<UserDto, User>()
.ForMember(dest => dest.UserId, options => options.MapFrom(async src => await sequence.GetNext()));
}
}
我调用异步方法只是为了演示我到底想要实现什么
AutoMapper 配置文件不支持 MapFrom 表达式中的异步方法。这是因为 AutoMapper 被设计为一个在内存中执行映射操作的同步库。如果您需要调用异步方法来获取一些额外的数据,您有几个选择:
• 映射完成后,您可以使用AfterMap 方法执行异步操作。此方法接受可以标记为异步的 Action
public class Profile : AutoMapper.Profile
{
public Profile(ISequence sequence)
{
CreateMap<UserDto, User>().ForMember(dest => dest.UserId, options => options.Ignore())
.AfterMap(async (src, dest) => dest.UserId = await sequence.GetNext());
}
}
• 您可以使用ProjectTo 方法创建可由底层数据提供程序异步执行的LINQ 投影。此方法允许您在 Select 表达式中使用异步方法。例如:
var users = await context.UserDtos
.ProjectTo<User>(configuration, src => sequence.GetNext())
.ToListAsync();
• 您可以使用实现 IValueResolver
public class UserIdResolver : IValueResolver<UserDto, User, int>
{
private readonly ISequence _sequence;
public UserIdResolver(ISequence sequence)
{
_sequence = sequence;
}
public async Task<int> Resolve(UserDto source, User destination, int destMember, ResolutionContext context)
{
return await _sequence.GetNext();
}
}
public class Profile : AutoMapper.Profile
{
public Profile(ISequence sequence)
{
CreateMap<UserDto, User>().ForMember(dest => dest.UserId, options => options.MapFrom(new UserIdResolver(sequence)));
}
}