Добавить контекст во время отображения - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть класс с набором Thing s, который можно идентифицировать по Id в сочетании с ThingCollectionId.

Соответствующий DtoThing содержит только Idи я хотел бы загрузить свойство PropertyNotInDto из всемирно известного класса ThingCollections при отображении DtoThing на Thing.

Это может быть достигнуто с помощью IMappingAction на DtoMyClass дляMyClass сопоставления, но для этого требуется, чтобы я перестроил Список вещей и добавил код сопоставления в MyDtoClass вместо DtoThing.

// sources for mapping
public class MyClass {
    public Guid ThingCollectionId {get;set;}
    public Dictionary<Thing, MyClassB> Things {get;set;}
}
public class Thing {
    public int Id {get;set;}
    // other properties
    public string PropertyNotInDto {get;set;}
}
// targets for mapping
public class DtoMyClass {
    public Guid ThingCollectionId {get;set;}
    public Dictionary<DtoThing, DtoMyClassB> Things {get;set;}
}
public class DtoThing {
    public int Id {get;set;}
    // no other properties are saved in the DtoThing class
}
// global
public class ThingCollections {
    public Dictionary<Guid, List<Thing>> ThingCollections {get;}
}

Есть ли способ добавить ThingCollectionId кконтекст, который можно использовать, когда используется код отображения для DtoThing на Thing?

Мой воображаемый синтаксис будет выглядеть примерно так:

 CreateMap<DtoThing, Thing>().AdvancedMapping<ThingMappingAction>();

, где ThingMappingAction имеетдоступ к ThingCollectionId.

Мой текущий подход выглядит следующим образом:

CreateMap<DtoMyClass, MyClass>().AfterMap<MyClassMappingAction>();
...
public MyClassMappingAction : IMappingAction<DtoMyClass, MyClass> {
    private ThingCollections ThingCollections {get;}
    public MyClassMappingAction(ThingCollections thingCollections){
       ThingCollections = thingCollections;
    }
    public void Process(MyDtoClass source, MyClass target) {
        // fix target.Things with ThingCollectionId, Thing.Id and ThingCollections
    }
}

Но это особенно раздражает, поскольку Thing используется в нескольких свойствах и требует специального кодадля каждого такого экземпляра, который нужно добавить в MyClassMappingAction.

1 Ответ

0 голосов
/ 04 марта 2019

Я достиг этого, добавив ThingCollectionId к контексту в BeforeMap и используя ITypeConverter<DtoThing, Thing> для повторного доступа к нему.

CreateMap<DtoMyClass, MyClass>().BeforeMap((dto, myclass, context) => context.Items["ThingCollectionId"] = dto.ThingCollectionId);
CreateMap<DtoThing, Thing>().ConvertUsing<ThingTypeConverter>();

public ThingTypeConverter: ITypeConverter<DtoThing, Thing> {
    private ThingCollections ThingCollections {get;}
    public MyClassMappingAction(ThingCollections thingCollections){
       ThingCollections = thingCollections;
    }
    public Thing Convert(DtoThing source, Thing destination, ResolutionContext context) {
        // Get the correct ThingCollection by ThingCollectionId
        var thingCollection = ThingCollections[(Guid)context.Items["ThingCollectionId"]];
        // Get the correct Thing from the ThingCollection by its Id
        return thingCollection.First(t => t.Id == source.Id);
    }
}

Это заменит вызов AfterMap и MyClassMappingAction, которыеРанее были использованы.Таким образом, код отображения для Thing не содержится в отображении для MyClass, и больше нет необходимости заново создавать словарь MyClass.Things вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...