Предположим, что у нас есть метод службы, который выполняет некоторые проверки безопасности, извлекает данные из БД и сторонней веб-службы, конструирует MyDataDTO
, записывает запись аудита обратно в БД.
И мы хотим хорошо структурированные, гранулированные коды ошибок, не так ли? Мы хорошие мальчики и следуем стандартным правилам обработки ошибок WCF:
[FaultContract(typeof(AccessDenied))]
[FaultContract(typeof(KeyNotFound))]
[FaultContract(typeof(WsFault))]
[FaultContract(typeof(DbFault))]
MyDataDTO GetData(string key);
Теперь мы добавляем новый метод, который обновляет данные. Метод вызывает GetData()
внутренне (или большую часть), выполняет проверку, обновляет данные. Таким образом, он должен иметь все ошибки GetData()
duplicated плюс добавить свои собственные ошибки:
[FaultContract(typeof(InvalidState))]
[FaultContract(typeof(DataNotValid))]
[FaultContract(typeof(AccessDenied))]
[FaultContract(typeof(KeyNotFound))]
[FaultContract(typeof(WsFault))]
[FaultContract(typeof(DbFault))]
void UpdateData(MyDataDTO data);
Пока все хорошо. Это позволяет нам даже генерировать документацию XML, которую мы можем предоставить потребителям нашей службы, чтобы они знали, какие коды ошибок они могут ожидать.
Теперь представьте, что у нас есть 10 сервисов с 10 методами, такими как выше (или даже более сложными). И определение всех этих контрактов на неисправности становится кошмаром, поскольку это довольно подверженный ошибкам процесс:
- Невозможно определить общие ошибки (например, DbFault) для всей службы
- Вы не можете гарантировать, что неисправность, определенная в контракте на операцию, действительно будет возвращена (проблемы с копированием)
- Вы не можете гарантировать, что вы не пропустили какую-либо ошибку, чтобы добавить к операционному контракту
Не учитывайте здесь версию интерфейса:)
Итак, вы получили изображение, если вы поддерживаете сервисы WCF на производстве. Должны ли мы вообще отказаться от контрактов на неисправность и использовать старый добрый C-стиль (например, иметь базовый класс DTOBase
с свойством ErrorCode)? Уменьшить гранулярность ошибок? Как убедиться, что документация правильная/актуальная? Меня интересуют некоторые лучшие практики.