⬆️ ⬇️

A little about unconventional mapping

Many people know about the excellent library AutoMapper . With the transformation of Entity -> Dto problems usually does not occur. But how to handle reverse mapping when aggregation root comes to API? Well, if you read and write - the contexts are separated and you can write from Dto . More often, however, you need to select the corresponding entities from the ORM by Id and save the aggregate as a whole. Occupation is a dreary, but often amenable to automation.



We declare such TypeConverter:



public class EntityTypeConverter<TDto, TEntity> : ITypeConverter<TDto, TEntity> where TEntity: PersistentObject, new() { public TEntity Convert(ResolutionContext context) { //    DbContext // , ServiceLocator  ,      IOC        // http://stackoverflow.com/questions/4204664/automapper-together-with-dependency-injection var dc = ApplicationContext.Current.Container.Resolve<IDbContext>(); var sourceId = (context.SourceValue as IEntity)?.Id; var dest = context.DestinationValue as TEntity ?? (sourceId.HasValue && sourceId.Value != 0 ? dc.Get<TEntity>(sourceId.Value) : new TEntity()); // , reflection,         . //   Expression Trees,      //      Dto    var sp = typeof(TDto) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(x => x.CanRead && x.CanWrite) .ToDictionary(x => x.Name.ToUpper(), x => x); var dp = typeof(TEntity) .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(x => x.CanRead && x.CanWrite) .ToArray(); //       foreach (var propertyInfo in dp) { var key = propertyInfo.PropertyType.InheritsOrImplements(typeof(PersistentObject)) ? propertyInfo.Name.ToUpper() + "ID" : propertyInfo.Name.ToUpper(); if (sp.ContainsKey(key)) { //     ,      propertyInfo.SetValue(dest, key.EndsWith("ID") && propertyInfo.PropertyType.InheritsOrImplements(typeof(PersistentObject)) ? dc.Get(propertyInfo.PropertyType, sp[key].GetValue(context.SourceValue)) : sp[key].GetValue(context.SourceValue)); } } return dest; } } 


And create mapping:



 AutoMapper.Mapper .CreateMap<TDto, TEntity>() .ConvertUsing<EntityTypeConverter<TDto, TEntity>>(); 


')

Source: https://habr.com/ru/post/307378/



All Articles