#c# #cqrs
#c# #cqrs
Вопрос:
В настоящее время я работаю над системой CQRS.
Он использует команды и события, что является стандартной практикой. Команды и события просто .ЧИСТЫЕ классы, но эти классы часто содержат несколько идентификаторов в качестве свойств, и все эти идентификаторы являются идентификаторами Guid.
Это приводит к проблеме при построении классов. Существует большой, если не огромный риск, что кто-то в команде вызовет конструктор с параметрами в неправильном порядке. Вы можете себе представить, насколько эта простая проблема будет разрушительной, т.Е. OrderID присваивается CustomerID и наоборот.
Итак, я ищу идеи, как это решить.
У меня самого есть несколько идей.
- Создайте отдельный тип для каждого идентификатора. Т.е. замените guid множеством типов. Это очевидное решение OO. Но мне это не нравится по ряду причин.
- Согласованное именование и Unittesting: если мы всегда называем наш идентификатор как Id. Потенциально мы можем проверить, что список параметров у вызывающего и вызываемого абонентов одинаковый (или похожий). И игнорируйте случаи, когда мы просто используем Guid.NewGuid(). Однако тест не простой. Для параметров вызываемого метода довольно легко получить список параметров, используя Reflection или Mono.Reflection . Для вызывающего абонента это другое дело. Например, переменные в методе могут быть оптимизированы. Итак, для тестирования вызывающего абонента нам нужно будет сделать что-то другое, кроме отражения, например, в стиле stylecop.
В целом, я не согласен ни с одной идеей и хотел бы что-то более простое или, возможно, готовое решение?
Комментарии:
1. Использование дискретного типа является «самым безопасным» внутри системы типов, но это срабатывает только тогда, когда значения могут быть случайно пересечены или перепутаны до другого уровня. Согласованное именование является хорошим независимо от того, и в любом случае требуется правильное тестирование (для семантической проверки, например, упорядочения полей с одинаковым типом). (Кроме того, использование другого типа / дискретного типа не имеет строгого отношения к ООП.)
2. Этот вопрос, по-видимому, не по теме, поскольку он не касается конкретной проблемы программирования и лучше подходит для programmers.stackexchange.com .
3. Кроме того, я не уверен, что это действительно имеет какое-либо отношение к CQRS. Это больше связано с передачей значений в качестве параметров конструктору или методу с более чем одним параметром одного и того же типа. Ответы, безусловно, будут самоуверенными и могут сильно отличаться.
4. Примените политику использования именованных аргументов.
5. Интересно. На самом деле это может быть лучшим решением. Но только если это возможно на определенных сборках. Я посмотрю, возможно ли это с помощью Resharper.
Ответ №1:
Отдельный тип для каждого идентификатора — хорошее решение, но мне это тоже не нравится.
Вызовы методов модульного тестирования — очень сложная проблема. Согласованное именование всегда хорошо.
На мой взгляд, слишком много параметров в командах / событиях — это первый сигнал о том, что что-то не так. Возможно, команда отвечает за слишком много вещей или некоторые параметры могут быть доставлены через инфраструктуру (например, текущий идентификатор пользователя).
РЕДАКТИРОВАТЬ: если вы можете убедиться, что не будет заказа и клиента (например) с одинаковым идентификатором (я думаю, что с GUID это безопасное предположение), вы можете убедиться, что оба существуют, и если кто-то где-то смешает эти два значения, во время выполнения всегда будет ошибка, поэтому ошибка будетбыть легко обнаруженным.
Комментарии:
1. Да, я согласен с вами до некоторой степени. Но проблема существует даже только с двумя параметрами.
2. Это правда, но невозможно заменить мышление машиной (я надеюсь на это ;)). Я добавил еще одну идею для решения этой проблемы
3. Ваше редактирование интересно, но я думаю, что для этого мне также понадобится фреймворк AOP. Поскольку я не могу просто проверить, что оба значения существуют — потому что они существуют — я должен проверить, соответствуют ли они правильному свойству. Или, возможно, я неправильно вас понимаю? В любом случае, с помощью AOP я мог бы ввести код, который проверял свойства, используя либо вашу, либо идею Питера Смита. Так что, возможно, AOP на самом деле является ответом…
4. Я имею в виду: проверьте, что клиент с заданным идентификатором действительно существует
5. Мне нужно было бы проверить это в методе проверки, который должен быть вызван конструктором. Отсюда и необходимость в платформе AOP для автоматического внедрения этого кода. Делать это вручную было бы утомительно.
Ответ №2:
Одной из идей было бы добавить к идентификатору GUID (поскольку они являются строками) идентификатор типа. Итак, псевдо-идентификатор GUID для идентификатора клиента xxyy
становится cust_xxyy
, однако, поскольку C # строго типизируется, я бы предложил class и properties в качестве правильного способа сделать это.
Комментарии:
1. Префикс — интересная идея, но я не понимаю, насколько она жизнеспособна. Тогда мне нужно будет проверять guid / string во всех вызовах методов? Ну, если бы я использовал som AOP framework, тогда, возможно. Ваше последнее утверждение совпадает с моим 1. идея.
2. Я знал об этом — просто поддерживал идею. Похоже, ключевым требованием является уникальная идентификация параметра. Лучше всего просто, и иногда, начиная с кажущегося возврата назад, просто должно произойти.
3. Вы правы. Но я бы загромоздил решение типами, потому что у всех объектов есть идентификатор. Я бы также потерял некоторые автоматические данные, которые у нас есть с идентификатором для баз данных. Но да, это определенно правильное решение с точки зрения пуристов, но, как уже говорилось, я ищу альтернативу.