Мы находимся в процессе переноса устаревшей системы на .NET, как для очистки архитектуры, так и для использования множества новых возможностей, которые просто нелегко реализовать в устаревшей системе.
Примечание. Читая мой пост перед его отправкой, я замечаю, что, возможно, в некоторых местах я описывал слишком быстро, т.е. затмил детали. Если есть что-то непонятное, оставьте комментарий (не ответ), и я увеличу как можно больше
Устаревшая система использует базу данных и 100% пользовательский написанный SQL повсюду. Это привело к появлению широких таблиц (т. Е. Множества столбцов), поскольку код, которому нужны данные, извлекает только то, что необходимо для работы.
В качестве части порта мы добавили слой ORM, который мы можем использовать в дополнение к пользовательскому SQL. ORM, который мы выбрали, это DevExpress XPO, и одна из функций этого также привела к некоторым проблемам для нас, а именно: когда мы определяем класс ORM для, скажем, таблицы Employee, мы должны добавить свойства для всех столбцов, в противном случае он не получит их для нас.
Это также означает, что когда мы получаем сотрудника, мы получаем все столбцы, даже если нам нужно только несколько.
Хорошая особенность использования ORM состоит в том, что мы можем поместить некоторую логику, связанную со свойствами, в одни и те же классы, не дублируя ее повсюду. Например, простое выражение для объединения имени, отчества и фамилии в «отображаемое имя» может быть помещено в качестве примера.
Однако, если мы пишем код SQL где-либо, либо в DAL-подобной конструкции, либо, ну, везде, нам нужно дублировать это выражение. Это неправильно и похоже на рецепт ошибок и кошмара обслуживания.
Однако, поскольку у нас есть два варианта:
- ORM, выбирает все, логика может быть записана один раз
- SQL, выбирает то, что нам нужно, нужно продублировать логику
Тогда мы придумали альтернативу. Поскольку объекты ORM генерируются кодом из словаря, мы решили также создать набор тупых классов. Они будут иметь одинаковое количество свойств, но не будут одинаково связаны с ORM. Кроме того, мы добавили интерфейсы для всех объектов, также сгенерированных, и заставили и ORM, и объекты dum реализовать этот интерфейс.
Это позволило нам перенести часть этой логики в методы расширения, связанные с интерфейсом. Поскольку немые объекты несут достаточно информации, чтобы мы могли подключить их к нашим SQL-классам, и вместо возвращения DataTable мы можем получить обратно список с доступной логикой, похоже, это работает.
Однако это привело к другой проблеме. Если я хочу написать фрагмент кода, который отображает или обрабатывает сотрудников только в том контексте, в котором мне нужно знать, кто они (то есть их идентификатор в системе), а также их имя (имя, отчество и фамилия), если Я использую этот тупой объект, у меня нет гарантии от компилятора, что код, который вызывает меня, действительно предоставляет все эти вещи.
Одно решение предназначено для того, чтобы сообщить объекту, каким свойствам были присвоены значения, и попытка прочитать неназначенное свойство завершается с исключением. Это дает нам возможность во время выполнения выявлять нарушения контракта, когда код не передает достаточно информации.
Это также выглядит неуклюже для нас.
В общем, я хочу получить совет, если кто-то еще находился или находится в этой ситуации, и какие-либо советы или рекомендации, которые вы можете дать.
В настоящее время мы не можем разбивать таблицы. Устаревшее приложение все еще будет существовать в течение нескольких лет из-за размера порта, и код .NET не является проектом типа выпуска в течение 3 лет, но будет постепенно внедряться в выпуски. Таким образом, и устаревшая система, и код .NET должны работать с одними и теми же таблицами.
Мы также знаем, что это не идеальное решение, поэтому, пожалуйста, воздержитесь от совета типа «Вы не должны были делать это так». Нам это хорошо известно:)
Одна вещь, которую мы рассмотрели, - это создание файла XML или аналогичного с «контрактами». Таким образом, мы можем поместить в этот XML-файл что-то вроде этого:
- Существует класс Employee с этими 50 свойствами
- Кроме того, у нас есть эти 7 вариантов для различных частей программы
- Кроме того, у нас есть эти 10 частей логики, для каждого из которых требуются свойства X, Y и Z (X, Y и Z варьируются между этими 10)
Это может позволить нам сгенерировать код этих 8 классов (полный класс + 7 меньших вариаций) и заставить генератор обнаружить, что для варианта № 3 присутствуют свойства X, Y и K, и я могу затем связать код для логики или интерфейсы, в которых логика нуждается в этом классе автоматически. Это позволило бы нам иметь несколько различных типов классов сотрудников с различной степенью охвата свойств и иметь генератор, автоматически добавляющий в него всю логику, которая будет поддерживаться этим классом.
Мой код может сказать, что мне нужен сотрудник типа IEmployeeWithAddressAndPhoneNumbers.
Это тоже выглядит неуклюже.