Расширяет функционал библиотеки AutoMapper добавляя асинхронность
Примеры использования Examples
Install-Package AsyncMapper
Пример:
var person = new Person() { name = "Иван", phone = "+7(916)123-45-67" };
Worker worker = await mapper.Map<Worker>(person);Маппер можно настроить двумя способами:
AsyncProfile- конфигурация находится в отдельных классах
public class ExampleProfile : AsyncProfile {
public ExampleProfile() {
/*конфигурация*/
}
}AsyncMapperConfiguration- в коде программы
var asyncConf = new AsyncMapperConfiguration(cfg => { /*конфигурация*/ });
var mapper = asyncConf.CreateAsyncMapper();В AsyncMapperConfiguration можно подключить AsyncProfile с помощью cfg.AddAsyncProfile<TProfile>()
CreateAsyncMap - создать мапу
Конфигурация происходит также, как в AutoMapper. Добавлены следующие расширения:
ForMemberAsync- конфигурация для отдельного поля/свойстваAddResolver- использовать резолверAddMemberResolver- использовать резолвер из указанного поля в указанное поле
AddAsyncResolver- эквивалентForMemberAsync -> AddResolverIncludeMap- эквивалентIncludeBaseизAutoMapper- при использовании
IncludeBaseасинхронная конфигурация игнорируется
- при использовании
Пример
CreateAsyncMap<Person, Worker>()
.ForMemberAsync(x => x.Phone, o => o.AddResolver<PersonToWorkerResolver>())
.ForMemberAsync(x => x.Name, o => o.AddMemberResolver<LoginToNameResolver, string>(y => y.Login))
.IncludeMap(typeof(PersonBase), typeof(WorkerBase))
// конфигурация AutoMapper
.ForMember(x => x.Id, o => o.MapFrom(y => y.Id))
.ForMember(x => x.Email, o => o.MapFrom<PersonEmailResolver>())Асинхронная конфигурация может быть смешана с синхронной в любом порядке
Внимание! Использование асинхронной конфигурации на синхронной мапе (CreateMap из AutoMapper) приведет к ошибке. Асинхронная мапа должна быть создана только через CreateAsyncMap.
IAsyncValueResolver- аналогIValueResolverIAsyncMemberValueResolver- аналогIMemberValueResolver
Пример
public class ExampleResolver : IAsyncValueResolver<From, To, int> {
public async Task<int> Resolve(From source, To destination) {
/* код */
}
}
public class ExampleMemberResolver : IAsyncMemberValueResolver<From, To, string, int> {
public async Task<int> Resolve(From source, To destination, string sourceMember) {
/* код */
}
}Внимание! В асинхронных резолверах функция Resolve должна выполняться асинхронно. Если на вашей функции Resolve висит варнинг CS1998, маппинг может выполняться медленнее.
Маппинг одного объекта
Task<TDestination> Map<TDestination>(object source);
Task<TDestination> Map<TSource, TDestination>(TSource source);
Task<TDestination> Map<TSource, TDestination>(TSource source, TDestination destination);Маппинг нескольких объектов в IEnumerable
Task<IEnumerable<TDestination>> Map<TSource, TDestination>(IEnumerable<TSource> source);
Task<IEnumerable<TDestination>> Map<TDestination>(IEnumerable<object> source);Чтобы получить доступ к синхронному мапперу, обращаемся к полю Sync
var workers = mapper.Sync.Map<Worker>(people);Внимание! При сихронном маппинге асинхронная конфигурация игнорируется. Рекомендуется маппить синхронно только если мапа не содержит асинхронную конфигурацию (была создана с помощью CreateMap)
Install-Package AsyncMapper.DependencyInjection
services.AddAsyncMapper(typeof(ProfileMarkerType));ProfileMarkerType - пустой класс, унаследованный от AsyncProfile. Используется для обозначения сборки, в которой находятся классы AsyncProfile с конфигурацией
ProfileMarkerType : AsyncProfile { }Маппер получается через интерфейс IAsyncMapper
ServiceProvider.GetService<IAsyncMapper>()DI может быть использовано в резолверах
public class ExampleResolver : IAsyncValueResolver<...> {
public ExampleResolver(IService service) {
/* код */
}
}Для корректной работы достаточно
- Заменить сервис маппера в DI
- Заменить наследование профилей с
ProfileнаAsyncProfile - Маппинг (2 способа)
- Заменить синхронный маппинг на асинхронный (
mapper.Map(...)->await mapper.Map(...)) - Оставить синхронный маппинг (
mapper.Map(...)->mapper.Sync.Map(...))
- Заменить синхронный маппинг на асинхронный (
Для увеличения производительности стоит перевести резолверы на асинхронность где это возможно