Pull to refresh

Comments 14

UFO just landed and posted this here
да, спасибо за линк. но это тоже своего рода кеширование
Если же определиться с форматом данных, а именно xml, то тут наиболее естественным и удобным был бы xslt
У нас система работает с множеством внешних API с различными форматами. Привязка к XML свяжет нам руки. И еще, в большинстве случаев у нас идет конвертация во внешние форматы прямо из модели данных (вычитанной из БД), которая является тоже контейнером. Т.е. шаги (1-2) исключаются
Правильно ли я понимаю, что если структура документа источника, либо назначения поменяется, то придется править код? Если так, то не такой уж и универсальный конвертер получается… Вот если бы пользователь мог загрузить файл-источник, и затем смаппить его на файл-назначение, то универсальность была бы выше. Не пробовали решать такую задачу?
Придется менять настройки правил. В примере статьи правило возращает заполненный Msrp объект. Это сделано для простого примера и не совсем универсальное правило. В реальном коде мы стараемся делать максимально универсальные правила, которые могут работать с любой структурой. Например можно создать три правила для каждого узла: Vehicle.Msrp, Vehicle.Msrp.Currency, Vehicle.Msrp.Value, тогда они будут возращать скалярные значения и эти правила можно применить многократно.
Как выглядит SplitAndCalc? Я не пойму что за оверинженеринг (и вообще зачем статья и xml).

У вас есть 2 типа, входной, используемый для десериализации, экземпляр которого вы передаете в качестве параметра конвертора и выходной, тип, возвращаемый конвертором, конструируется конвертором из входного (создается экземпляр). Что за «правила», зачем «рефлексия» (сериализация/десериализация, я так понимаю не в счет, выполняется стандартными средствами), какую «проблему» такая громоздкая архитектору призвана решить?

По идее вам достаточно создать по одному конвертору для каждой комбинации входных/выходных типов. Все параметры (например, «РУБ»/"$" для денег) можно либо передавать в качестве параметров конструктора, либа десериализуя экземпляры десериализаторов, в любом случае где-то должна быть структура содержащая все такие конверторы и некое правило (ключ словаря?) которым выбирается/загружается (lazy initialization?) нужный экземпляр.

Все конверторы работают с конкретными типами (generics, (T, V)), никаких SplitAndCalc не нужно. Я чего-то не понимаю?

targetObject.Currency = ‘TargetCurrency’;

Шта? Это псевдокод?
SplitAndCalc — делает следующее парсит «31000 USD» на 31000 и «USD», заходит во внешний источник данных (например БД) берет курс USD/RUB, пересчитывает стоимость в рубли и возращает значение.
Правило это код, который для заданного пути возращает значение для заполнение узла.
Да, справочники правил, и их применения должны где-то храниться.
Про ‘TargetCurrency’ — это опечатка, исправил
Мысль статьи в том, что бы создать параметризуемый конструктор конвертаций различных узлов, что бы пользователь мог не сильно вдаваясь в подробности реализации встроенных правил мог ими пользоваться и главное читать (не код). Ну и XML это просто пример формата, а так конвертер способен работать с любыми форматами.
Рефлексию мы используем для быстрого достпа к данным объекта и сборки целевого экземпляра контейнера.
Найду время допишу в статью еще одно правило, для общего понимания идеи.
Может я что не так понял в постановке задачи, но почему не захотели использовать AutoMapper (или аналог) в связке с (де)сериализаторами, которые вместе можно положить в DI-контейнер и получить и мощь, и простоту, и конфигурируемость?

У меня была похожа задача — мы реализовывали работу с внешними клиентами по разным протоколам и не хотели писать конвертеры входных/выходных данных для каждого протокола/клиента (от клиента зависели некоторые правила преобразования и контроля данных). В итоге у нас получилась цепочка: входной формат — десериализация — конвертация во внутреннее представление — обработка — конвертация во внешнее представление — сериализация — выходной формат.
Через контейнер настраивались и конвертаторы и сериализаторы. На каждом этапе (включая обработку) через тот же контейнер были доступны компоненты для доступа к данным…
Если не ошибаюсь, AutoМapper это меппер типов, причем детерменированный (можно настроить только из кода).
Например, нужно заполнить класс у которого член Product.Item c типом Object. Согласно требований задачи, в Item можно назначить экземпляр объекта один из типов Struct1 и Struct2, заполнение которых выполняется по разному — не уверен, что маппер с ним справится без костылей
Например, нужно заполнить класс у которого член Product.Item c типом Object. Согласно требований задачи, в Item можно назначить экземпляр объекта один из типов Struct1 и Struct2, заполнение которых выполняется по разному — не уверен, что маппер с ним справится без костылей

Да легко, кстати. Там и конвертеры есть, и условное заполнение.

Да, в автомаппере гибкости много.
Да и у вас кода не мало. Может с автомапером кода в конфигурации станет чуть больше, но обвязки станет меньше, как мне кажется… да и дебажить и тестировать такой подход проще.
Или есть принципиальная потребность хранить правила в виде текста вне кода программы?
(тут, кстати, тоже есть варианты, как прикрутить конфиг из текста к автомапперу)
Да, нам нужен конфиг регулируемый пользователем. Думаю если конфиг из текста туда получится затащить, то может и получится, надо пробовать. В любом случае это будет надстройка над automapper (сразу приходит мысль, а не сделать ли лайт аналогию с маппером с нуля)
Думаю если конфиг из текста туда получится затащить, то может и получится, надо пробовать.

Да нет проблемы, прочитали конфиг, вызвали набор методов на MappingConfiguration.


сразу приходит мысль, а не сделать ли лайт аналогию с маппером с нуля

А зачем? NIH?

Sign up to leave a comment.

Articles