Копирование моделей между слоями - PullRequest
8 голосов
/ 27 августа 2010

При перемещении по слоям очень утомительно выполнять назначения справа налево как способ заполнения моделей.Например:

employeeViewModel.FirstName = employeeModel.FirstName;
employeeViewModel.LastName = employeeModel.LastName;
...

Итак, мы можем построить ModelCopier, который использует отражение для копирования моделей:

var employeeViewModel = ModelCopier.Copy<EmployeeViewModel>(employeeModel);

Этот метод значительно упрощает задачу.Тем не менее, есть несколько вещей, которые весьма беспокоят насчет этого:

  • Мы фактически утратили способность отслеживать использование свойств в объектах источника и назначения.Например, поиск использования (в Resharper) свойства FirstName не выявляет случаи ModelCopier.
  • Если мы изменим имя свойства в классе источника или назначения, мы можем непреднамеренно вызвать исключения времени выполнения, так как мы можемМы не понимаем, что нам нужно обновить как исходный, так и целевой класс.

На одном конце спектра мы можем использовать отражение, которое очень просто, но за счет ремонтопригодности.Противоположный конец спектра очень утомителен, но очень ремонтопригоден.

Отражение (легкое и опасное) <-----> Прямое назначение (утомительное и удобное в обслуживании)

Мне интересно, если кто-нибудь нашел компромисс, который предлагаетпростота использования отражения для копирования с возможностью сопровождения прямого назначения.

Одним из решений, которое мы развлекли, было создание плагина, который будет генерировать методы расширения, которые будут обрабатывать назначение свойств для каждого случая.Другими словами, создайте инструмент, который будет обрабатывать утомительную часть.

РЕДАКТИРОВАТЬ:

Пожалуйста, поймите, что этот вопрос не о том, какой инструмент отображения использовать.Я пытаюсь понять, как мы можем пользоваться преимуществами картографирования на основе отражений, а также преимуществами обслуживания, которое обеспечивается прямым назначением (или контрактом карты свойств).

Ответы [ 5 ]

10 голосов
/ 27 августа 2010

Серьезно, используйте AutoMapper .Позволяет настроить преобразования из одного типа в другой тип.Любые изменения в именах свойств нарушат конфигурацию автоматического обработчика, отражение которой не будет:

Mapper.CreateMap<SiteDto, SiteModel>();
Mapper.CreateMap<SiteModel, SiteDto>();

Затем, чтобы отобразить в и из, вы просто выполните следующее:

SiteDto dto = Mapper.Map<SiteModel, SiteDto>(targetModel);
SiteModel model = Mapper.Map<SiteDto, SiteModel>(targetDto);
3 голосов
/ 27 августа 2010

Вероятно, компилятор не выполняет необходимый тест во всем коде ... вот где на помощь приходит модульное тестирование.Если вы определили тест для преобразования между классами в разных слоях (да, все возможные преобразования, которые вам нужно выполнить, иначе как вы можете быть уверены, что ваш подход к отражению будет работать в каждой ситуации, когда вы работаете?), ПростоЗапуск теста скажет разработчику, который изменил имя свойства, что решение больше не проходит все тесты.Вы должны запускать каждый тест (модульный тест, а не интеграционный тест) каждый раз, когда вы хотите зарегистрировать свой исходный код ... и это не должно быть пару месяцев написания кода:))

Так что ядействительно голосуйте за использование подхода отражения, пряного с ложкой подхода модульного теста.

1 голос
/ 27 августа 2010

Мне любопытно, если бы кто-нибудь нашел компромисс, который предлагает простоту использования отражения для копирования с возможностью сопровождения прямого назначения.

Звучит так, будто вы пытаетесь получитьиспечь и съесть.

Это проблема, с которой динамические языки сталкиваются каждый день.Там нет волшебной таблетки.Либо выполняйте задания слева направо и получите защиту компилятора, либо включите критические задания в модульные тесты.

Моя интуиция говорит мне, что это проблема дизайна, а не кода.

0 голосов
/ 28 августа 2010

ваши требования выходят за рамки времени выполнения (реализации) как такового, поскольку вам (и всем нам) нужны графики зависимостей и т. Д. Это означает, что динамическое обнаружение с отражением отсутствует.Кажется, вам нужно решение во время компиляции.Кроме предложения @ amaca о плагине для генерации кода (который вы можете легко написать), какие еще варианты могут быть?

0 голосов
/ 27 августа 2010

Одним из способов было бы написать отдельную утилиту, которая использует отражение, чтобы получить имена свойств из модели, а затем записать исходный код для предоставления свойств.

...