Рассмотрим:
Как вы сообщаете сообщения / ошибки сервисного уровня верхним уровням, используя MVP?
Я не уверен, как конкретно помочь здесь. Во-первых, я не очень разбираюсь в ваших настройках и не знаю ничего о деталях WCF. Во-вторых, я не получаю комментарий о неприязни к исключениям для бизнес-логики ... но я предполагаю, что вы имеете в виду «проверку бизнеса», как вы заявили в другом месте (в этом случае, это имеет смысл для меня).
В моем невежестве, похоже, у вас есть начало вашей собственной схемы, так что, возможно, у вас много свободы. И, конечно, многие вещи могут работать. Итак, вот несколько альтернатив:
Способ связи
Вы можете просто попробовать свой подход и посмотреть, как вам это нравится. IMO, это смешивание проблем для проверки и совместной работы (иногда это не помогает, особенно если вы начинаете спрашивать, как обрабатывать сбои). Command-Query, кроме всего прочего, это классическая проблема return-vs-throw, и на этой границе у вас есть право выбрать любой из них, пока он работает.
Если у вас есть фреймворк для вашего MVP, вы можете посмотреть, есть ли в нем что-то встроенное.
За исключением этого, вы можете изменить отношения PL / SL, чтобы явно отделить проверку от операции. Вот так:
IList<Error> Validate_Operation1(Entity1 a){}
Entity2 Operation1(Entity1 a){}
Или, чтобы быть сумасшедшим:
public interface ICommand
{
IList<Param> Params { set; }
IList<Error> Validate();
void Execute();
}
Если бы я строго отличал «Ошибки валидации» от «Ошибки пост-валидации» и «Неожиданные ошибки», я мог бы сделать выше. Возвращение проблем проверки в результате запроса проверки, конечно, не является «исключительным».
Помимо всего этого, вы можете подумать о том, чтобы немного более абстрактно понять, что вы собираетесь делать с ошибками после проверки. Некоторые из них могут быть действиями пользователя, независимо от того, связаны ли они с бизнесом. «Datatraveler кажется поврежденным. Пожалуйста, переформатируйте флэш-накопитель». Или даже предупреждения типа «Настройки не найдены, дополнены настройками по умолчанию». Если ваше приложение обладает высокой интерактивностью, ваша болтливая SL может использовать более общий механизм для отправки вопросов проверки.
Содержание сообщения
Я не считаю ваши сущности Response-class-with-error-enums-and-null-юридических лиц миль отличающимися от определения вашего собственного класса ошибок или исключения, если честно. Я не особо разбираюсь в «многоцелевом» возврате, подобном этому, но есть подход для такого подхода: многие EventArgs или асинхронные аргументы обратного вызова реализованы так, чтобы иметь информацию об ошибке, отмене и результатах.
Что касается перечисленных вами недостатков, я не уверен, насколько широка иерархия ошибок, когда вы говорите, что «PL должен обрабатывать все случаи, определенные в exceptionInfo», поэтому простите, что я предположил наихудшее здесь. Выбранное вами транспортное средство (исключения, простые строки или перечисление исключения) не меняет того факта, что если вы распознаете 762 различных ошибки, вы узнаете 762 различных ошибки.
Но это не значит, что ваши докладчики должны четко учитывать каждого из них. Вы получаете выгоду от контекста - вы знаете, что вы не получите «Имя пользователя было пустым» после того, как пользователь уже вошел в систему и проверил баланс ипотеки. (И если вы это сделаете, вам, вероятно, следует рассматривать это как «непредвиденную ошибку при проверке баланса. Пожалуйста, повторите попытку позже» и зарегистрируйте стек вызовов, верно?)
Так что вашему докладчику нужно знать только короткий список, который относится к его контексту, а не все. Все остальное "Неожиданно ...".
И, так как вы определяете свой собственный класс Error, вы можете рассмотреть возможность помещения своих ошибок в строковые ресурсы и привязывания идентификатора ресурса к конкретной ошибке при создании объекта. Затем, вместо индивидуальной обработки случаев, многие из них могут быть решены одним и тем же действием: Получить идентификатор, загрузить строку, показать строку, выполнено. Выписка переключателя не требуется.