Создание простейшей WCF-службы. Часть 1.

Примечание автора: эта статья была написана в районе 2008 года, и, скорее всего, она уже морально устарела. Однако, судя по отзывам, все еще кому-то полезна. Статья разделена на несколько частей.

Часть 1, Часть 2, Часть 3

Введение

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

Сегодня я расскажу о том, как создать простейшую WCF-службу. Для примера будем использовать классический вариант — калькулятор.

Создание службы

Для создания нашего приложения мы будем использовать Visual Studio 2008. Итак, вызовем диалоговое окно создания нового проекта и выбираем шаблон проекта под названием «WCF Service Library» и дадим ему имя «WcfCalcService».

Проект сейчас состоит из трех основных файлов. Посмотрим, за что каждый из них отвечает.

1. App.config — файл конфигурации приложения. В этом файле также находятся настройки службы;

2. IService1.cs — файл с интерфейсом (контрактом) службы;

3. Service1.cs — файл с классом, реализующим интерфейс (т.е. функционал службы).

Контракт службы

Изначально VS открывает перед нами файл IService1.cs. Это вполне оправдано, ведь разработка любой службы должна начинаться с определения того, что же она все-таки будет делать. Поменяем имя интерфейса на ICalcService (а также переименуем файл в ICalcService.cs). Заметьте, что перед объявлением интерфейса стоит атрибут ServiceContract. Это-то как раз и означает, что данный интерфейс является контрактом WCF-службы.

Примечание:

В комментарии перед кодом интерфейса написано:

// NOTE: If you change the interface name “IService1″ here, you must also update the reference to “IService1″ in App.config.

Что означает: «Если вы измените имя интерфейса «IService1» здесь, вам также нужно будет обновить ссылку на «IService1» в файле App.config». Мы это сделаем чуть позже, а этот комментарий можно удалить.

Примечание:

Не забывайте пользоваться рефакторингом, чтобы везде, где в коде упоминается IService1, его имя заменилось на ICalcService.

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


OperationContract

Примечание

Ниже описания интерфейса находится описание типаCompositeType, который VS создает для примера. Его можно удалить.

Итак, теперь файл ICalcService.cs выглядит следующим образом:


ServiceContract

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

Примечание

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

Вообще, я рекомендую все, используемые для обмена типы, выделять в отдельную сборку, особенно, если вам нужен еще и какой-то общий функционал этих типов. Существует еще один вариант — описать интерфейсы типов, а реализацию сделать различной на клиенте и сервере. Такой вариант хорош при создании более-менее больших и сложных систем. Есть и третья возможность. Студия, при создании ссылки на сервис (Service Reference, это мы рассмотрим подробнее в статье про создание клиентских приложений), автоматически скачивает метаданные (описание структуры и функционала сервиса в специальном формате — WSDL) и по ним генерирует все контрактные типы, но у этого подхода есть два минуса. Первый — у нас нет доступа к методам сгенерированного типа (VS их просто не создает). Второй — для автоматического создания ссылки на службу нужна работающая служба с открытыми метаданными. Это встречается очень редко, если вы хотите создать клиентское приложение для существующей чужой службы. Поэтому, думаю, моя точка зрения по этому вопросу вполне ясна.

CreateProject

Создание проекта с общими типами

Мы воспользуемся первым вариантом: создадим еще одну сборку, добавив в решение новый проект с шаблоном «ClassLibrary» и дав ему имя «CalcCommon».


Добавление ссылки на System.Runtime.Serialization

Добавление ссылки на System.Runtime.Serialization

Чтобы в нашей общей сборке были доступны атрибуты для контрактов, нужно добавить ссылку на сборку System.Runtime.Serialization (правой кнопкой по проекту — Add reference).

Теперь удалим из нового проекта все лишнее, создадим новый файл класса (для этого можно нажать сочетание клавиш Alt+Shift+C) и назовем его CalcOperationResult.cs. Так выглядит описание типа CalcOperationResult:

DataContract

Атрибут DataContract говорит о том, что данный тип используется для описания контракта данных службы и будетсериализуемым специальным диспетчером сериализации (System.Runtime.Serialization.DataContractSerializer). Соответственно DataMember говорит, что данный член класса относится к описанию контракта данных и будет сериализован тем же DataContractSerializer’ом.

Создадим еще один файл, где опишем перечисление CalcOperationType:

EnumDataContract

Как видите, для описания перечисления так же используется атрибут DataContract. А вот для членов перечисления нужен специальный атрибут EnumMember. В противном случае все значения типа перечисления будут передаваться в виде строки.

Примечание

Не забывайте в список используемых модулей добавлять строку:
using System.Runtime.Serialization;

AddReference

Добавление ссылки на общую сборку

Отлично! Осталось подключить к проекту службы сборку CalcCommon (правой кнопкой по проекту — Add Reference — закладка Projects) и наш интерфейс полностью готов (не забываем про using CalcCommon).


Продолжение следует — во второй части статьи.

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Добавить комментарий