решение wcf: один сервис несколько контрактов или много сервисов

Я использую .NET 4 для создания небольшого клиентского серверного приложения для клиента. Должен ли я создать одну гигантскую службу, которая реализует много контрактов (IInvoice, IPurchase, ISalesOrder и т. д.), Или я должен создать много служб, выполняющих один контракт на многих портах? Мои вопросы конкретно интересуют плюсы / минусы любого выбора. Кроме того, каков общий способ ответа на этот вопрос?

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

6 ответов


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

Не создавайте слишком много услуг. Избегайте ловушки, делая ваши услуги слишком мелкозернистыми. Попробуйте создать службы на основе функциональности. Этот методы, предоставляемые этими службами, также не должны быть мелкозернистыми. Вам лучше иметь меньше методов, которые делают больше. Избегайте создания подобных функций, таких как GetUserByID(int ID), GetUserByName(string Name), создавая GetUser(userObject user). У вас будет меньше кода, более простое обслуживание и лучшая обнаруживаемость.

наконец, вам, вероятно, понадобится только один порт, независимо от того, что вы делаете.


обычно вы создаете разные службы для каждой основной сущности, такой как IInvoice, IPurchase, ISalesOrder.

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


в приложениях реального времени у вас есть один контракт на обслуживание для каждого объекта, как счет-фактура, покупка и заказ на продажу будет иметь отдельный ServiceContract

однако для каждого контракта на обслуживание будут гетерогенные клиенты, такие как счет-фактура, будет вызываться backoffice через приложение windows с помощью netNamedPipeBinding или netTcpBinding, и в то же время клиентское приложение должно вызывать службу с помощью basicHttpBinding или wsHttpBindings. В основном вам нужно создать несколько конечные точки для каждой службы.


кажется, что вы смешиваете DataContract(s) и ServiceContract (s). Вы можете иметь один ServiceContract и много DataContract(ов), и это идеально подойдет вашим потребностям.


вы должны принять решение на основе ожидаемой нагрузки, необходимой расширяемости и будущей перспективы. Как вы написали "небольшое клиентское серверное приложение для клиента", это не дает четкого представления о предполагаемом использовании разработки. Ответ Мистера Бига тоже надо обдумать.

вы можете выдвинуть еще один вопрос, подкрепленный конкретными данными или подробностями о ситуации. Спасибо.


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

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

слишком много ServiceContracts на одной службе увеличит время его принимает для создания и использования прокси. Но, если вы только закончите с одной или двумя операциями по контракту, вы добавите сложности в систему с очень небольшим выигрышем. Это не научный рецепт, но хорошее эмпирическое правило можно сказать о 10-20 OperationContracts на ServiceContract.

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

еще одна вещь, которую нужно помнить, и это очень важно-всегда делать ваши методы как можно более общими. В WCF занимается DataContracts по причине. DataContracts означает, что вы можете отправлять любой объект на сервер и с сервера, пока известны DataContracts.

Так, например, у вас может быть 3 OperationContracts:

[OperationContract]
Person GetPerson(string id);

[OperationContract]
Dog GetDog(string id);

[OperationContract]
Cat GetCat(string id);

но, пока это все известные типы, вы можете объединить их в одну операцию, например:

[OperationContract]
IDatabaseRecord GetDatabaseRecord(string recordTypeName, string id);

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

наконец, вернитесь к ServiceContracts каждые несколько месяцев и удалите операции, которые не используются клиентами. Это еще один большой!