Неправильно ли переключать клиентскую логику на уровне службы?

У нас есть два клиентских приложения (веб-приложение и приложение-агент), которые обращаются к методам одной и той же службы, но с немного разными требованиями. Моя команда хочет контролировать поведение на стороне службы, передавая параметр ApplicationType каждому методу, который по сути представляет собой перечисление, содержащее имя вызывающего клиентского приложения, которое затем используется в качестве ключа для поиска в базе данных для настройки службы с помощью специфические для клиента опции.

Что-то в этом вызывает у меня беспокойство, поскольку я не думаю, что служба действительно должна знать, какой клиент ее вызывает. Мне говорят, что проще сделать это таким образом, чем динамически передавать загрузку опций через вызов метода.

Что-то не так с тем, что клиентское приложение сообщает службе, кто они? Или действительно нет разницы между передачей ключа конфигурации и набором параметризованных параметров?

Одна непосредственная проблема, которую я вижу, заключается в том, что если мы когда-либо откроем службу для другого клиента, управляемого третьей стороной, нам придется локально поддерживать их настройки конфигурации для них. На данный момент у нас есть оба клиентских приложения, так что это не такая большая проблема.

Как бы вы это сделали?


soa
person elwy    schedule 03.12.2008    source источник


Ответы (4)


В многоуровневом решении вы всегда должны рассматривать свои слои как луковичные слои, а зависимости всегда должны идти внутрь, а не наружу.

Таким образом, ваш уровень GUI/приложения должен зависеть от уровня бизнес-логики, уровень бизнес-логики должен зависеть от уровня доступа к данным и т. д.

Если вы не классифицируете клиентов (web, win, wpf, cli) или не обобщите их с помощью профилей клиентов (которые могут настраивать клиентские приложения), я бы никогда не передал имя вызывающего приложения, так как это сделало бы уровень бизнес-логики осведомленным и зависит от внешнего слоя.

О каких различиях мы говорим, которые будут зависеть от типа приложения? Если вы немного подробнее остановитесь на различиях, возможно, кто-то сможет дать полезный совет о других способах решения этой проблемы.

Но я бы точно поискал другие пути, прежде чем идти по описанному вами пути.

person Lasse V. Karlsen    schedule 03.12.2008

Нельзя ли создать два разных сервиса, по одному для каждого приложения? Две службы будут совместно использовать много кода или вызывать одну внутреннюю службу с разными параметрами в зависимости от того, какая внешняя служба была вызвана.

person activout.se    schedule 03.12.2008

С точки зрения дизайна это ничем не отличается от пользователей с разными профилями. С точки зрения безопасности, я надеюсь, что ваши приложения делают что-то, чтобы идентифицировать себя, чтобы пользователи одного приложения не нашли способ вызвать логику другого приложения как взлом. (Представьте себе приложение HR, используемое мафией и банком одновременно, один клиент был бы заинтересован во взломе приложения другого клиента на общем хосте приложений)

В .net дизайн не выглядит таким образом, потому что учетные данные живут в потоке (т. Е. Когда вы устанавливаете IIPrincipal, эта информация передается в потоке - она ​​передается вместе с каждым вызовом метода, но не как параметр.)

Возможно, то, что вы ищете с точки зрения более элегантного дизайна, — это атрибут ApplicationIdentity. Вам придется написать собственный, я не знаю ни одного в рамках прямо сейчас.

person MatthewMartin    schedule 03.12.2008

Это сложная тема для обсуждения без убедительного примера.

Вы правы, что так чувствуете. Отправка типа клиента для изменения поведения неверна. Это неплохая идея для ведения журнала... но это все.

Вот что я бы сделал:

  • Просмотрите каждый метод, чтобы увидеть, что должно быть другим и почему.
  • Создайте разные методы для разных применений. Название метода должно говорить само за себя. Если вам когда-нибудь понадобится нарушить совместимость, у вас будет больше контроля (при условии, что вы не используете систему управления версиями, которая была бы излишней для внутренней службы).
  • В некоторых случаях более подходящими являются параметры запроса (значения флагов/перечисления).
  • В некоторых случаях лучше знать операционную среду (особенно для безопасности данных). Операционная среда почти всегда отправляется во время запроса на вход. Что-то вроде «обслуживаемый»/«безопасный» (клиент-агент) и «автоматический»/«небезопасный» (веб-клиент). Теперь вы должны обменять ключ сеанса (файл cookie HTTP или идентификатор сеанса на уровне приложения). Сеансы, очевидно, не работают, если вам нужно быть на 100% апатридом, особенно если вы хотите масштабировать без репликации сеанса... если у вас есть такое требование, отправляйте структуру в каждом запросе.

Думайте о запросах как о функциях в вашем коде. Вы бы не добавили волшебный параметр, который меняет поведение функции. Вы бы создали несколько функций, каждая из которых ведет себя по-разному. Тот, кто использует функцию, принимает решение, какую из них вызывать.

Так почему же тип клиента такой неправильный? Тип клиента не имеет особого значения сам по себе. У него много значений, и со временем они могут меняться. Это просто информация, поэтому это удобно регистрировать. Операционная среда имеет особое значение.

Вот сценарий для рассмотрения: что, если будет разработан новый тип клиента, который немного отличается таким образом, что нарушит совместимость с исходным запросом? Теперь у вас есть два запроса. 2 клиента используют запрос A, а 1 клиент использует запрос B. Если вы передаете тип клиента в каждый запрос, ожидается, что сервер будет работать для всех возможных типов клиентов. Гораздо сложнее тестировать и поддерживать!!

person Graeme Wicksted    schedule 07.06.2012