Программирование, Сервис-ориентированные системы

Основы разработки WCF-служб. Часть 3. Разработка простой WCF-службы

В этой статье я расскажу о том, как создать простую WCF-службу на языке C# из приложения, созданного в предыдущей статье. Основы разработки WCF-служб. Часть 3. Разработка простой WCF-службы
Иван Артамоновhttps://artamonoviv.ru/images/icon/logo.png
Внимание! Эта статья была опубликована в 2012 году в книге "Разработка распределенных сервисно-ориентированных программных средств". Использование материалов из нее разрешено только при правильной библиографической ссылке (для докладов, курсовых работы, рефератов, дипломных и пр. научных работ) или url-ссылки (для сайтов). Библиографическое описание дано в конце статьи.
PDF-версия статьи: скачать
В этой статье я расскажу о том, как создать простую WCF-службу на языке C# из приложения, созданного в предыдущей статье.

Код, необходимый для разработки WCF-службы, был создан в предыдущей статье Основы разработки WCF-служб. Часть 2. Разработка простейшего приложения.

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

Создадим простую WCF-службу. С учетом ранее созданного кода решение этой задачи будет предельно простым.

1. Разработка службы.

Для начала откройте меню "Файл" : "Создать" : "Проект". В диалоговом окне создания нового проекта в правой области "Типы проектов" выберите "Visual C#" : "WCF". Среди шаблонов необходимо выбрать "Библиотека службы WCF". В нижней части окна введите имя "b_FirstService" и расположите проект в любом месте.

Нажмите "ОК" и подождите, пока Visual Studio создаст все необходимые файлы и "черновики".
В этой работе нам будет необходимо работать с правой (по умолчанию) областью окна среды разработки, которая называется "Обозреватель решений". Здесь показан иерархический список всех файлов, которые включает наша программа.

На данный момент в проект входят три файла: "App.config", "IService1.cs", "Service1.cs".

Два файла – "IService1.cs", "Service1.cs", это "черновики", которые были созданы автоматически вместе с небольшими участками тестового кода. Так как мы будем создавать службу на базе собственного кода, то необходимо удалить эти файлы. Щелкните правой кнопкой по "IService1.cs" и "Service1.cs" и удалите их.
Добавим в службу новый класс. Для этого щелкнем правой кнопкой по названию проекта b_FirstService в обозревателе решений и там "Добавить":"Класс…"

Появится окно "Добавление нового элемента" с выделенным элементом типа "Класс". В нижней части окна в поле "Имя" будет уже введено Class1.cs. Измените имя на "Book".

Нажмите "Добавить". В проект добавиться файл Book.cs (вы увидите его в "Обозревателе решений"), а перед вами откроет заготовка для этого класса в виде:

Нам необходимо добавить в этот класс ранее разработанный код. Для этого откройте код программы из статьи: Основы разработки WCF-служб. Часть 2. Разработка простейшего приложения. По умолчанию он должен находиться в файле Program.cs. Откройте файл "Program.cs" с помощью Блокнота или любого другого простого текстового редактора. Найдите в коде программы описание класса Book и перенесите в новый проект это описание. Вы должны получить что-то типа этого:

Обратим внимание, что уровень доступности класса Book должен быть public. Если это слово не стоит перед названием класса, то следует его указать.
Теперь наступает очень важный с точки зрения разработки службы момент. Как вы помните, функция "AddBooks" требует в качестве входного параметра экземпляр класса Book, а это значит, что значения этого класса необходимо будет передавать службе. Как уже говорилось, любые данные, получаемые и отправляемые службой, должны быть отмечены контрактами о данных (data contracts). Напомним, что контракты – это независимый от платформы способ описания того, что может выполнять служба для клиентов.
Перед тем, как отмечать контракты, необходимо подключить пространство имен, которое необходимо для работы с атрибутами контрактов. Перед строчкой namespace b_FirstService напишите:

Пространство имен System.Runtime.Serialization необходимо для сериализации и десериализации объектов.
Пометим класс и его переменные как контракт о данных и члены этого контракта.

В строчке перед строкой с названием класса пропишем атрибут [DataContract], а перед каждым элементом класса пропишем атрибут [DataMember]. Должно получиться так:

Добавим аналогичным способом в проект второй класс, который назовем "IWorkBook". Файл "IWorkBook.cs" должен по умолчанию содержать такой код:

Так как класс "WorkBook" из прошлой статьи содержал функции для работы со списком книг, то в службе эти функции должны быть обозначены сервисным контрактом. Как уже говорилось, сервисный контракт (service contract) – это описание тех функций, что реализует служба.

Для того чтобы обозначить контракт, необходимо создать интерфейс и класс, который будет реализовывать этот интерфейс. Переименуем "class IWorkBook" в "public interface IWorkBook".

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

Обратим внимание, что уровень доступности интерфейс IWorkBook должен быть public.

Теперь следует указать, что эти операции входят в сервисный контракт. Предварительно подключим пространство имен System.ServiceModel. Это пространство имен содержит необходимые классы и интерфейсы для реализации WCF. Можно сказать, что System.ServiceModel – это и "есть WCF".

Затем перед названием интерфейса пропишите атрибут [ServiceContract]. А перед каждой операцией - [OperationContract].

Должно получиться так:

Теперь остается лишь реализовать этот интерфейс. Создайте третий класс, назовем его WorkBook. Поставим уровень доступности его как public.

Далее необходимо указать, что этот класс реализует именно интерфейс IWorkBook. Поэтому после названия класса поставьте двоеточие и пропишите IWorkBook так:

А теперь перенесите все содержимое класса WorkBook в эту статью из Основы разработки WCF-служб. Часть 2. Разработка простейшего приложения. Кроме того, необходимо явно указать, что наш экземпляр службы единственный и принимает все запросы на себя. Для этого необходимо явно прописать поведение службы для управления параллелизмом. Укажите строчку

в качестве атрибута класса WorkBook.

Не забудьте подключить пространство имен System.ServiceModel . В итоге, должно получиться так:

На этом этапе создание кода службы завершено. Попробуйте построить решение ("Построение" : "Построить решение"), но НЕ ЗАПУСКАЙТЕ его. Если построение пройдет без ошибок, то можно приступить к следующему этапу.

2. Конфигурирование службы.

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

Конфигурирование службы в WCF можно проводить двумя основными путями: через файл "app.config" или непосредственно в коде службы. Первый способ дает возможность менять адреса и привязки службы, не прибегая к изменению ее кода. То есть вы можете заставить службу, которая раньше взаимодействовала с вашими приложениями на одном компьютере через привязку "NetNamedPipeBinding" (она не поддерживает сетевые коммуникации), работать с сайтами в интернете через привязку "BasicHttpBinding" только изменив ее настройки.

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

Мы начнем работать с самым простым способом конфигурирования – через "app.config".
Для этого щелкните правой кнопкой по файлу "App.config" в "Обозревателе решения" и выберите пункт "Edit WCF Configuration".

Перед вами откроется редактор конфигураций.

Заметим, что в "службах" (Services) у нас определена одна служба с именем b_FirstService.Service1. Это имя автоматически было создано VisualStudio и, так как мы изменили службу, его необходимо также изменить.

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

Далее в новом окне "Service Type Browser" необходимо найти библиотеку dll, которая содержит код нашей службы и которую мы недавно создали. По умолчанию она должна находиться по адресу "\b_firstservice\b_firstservice\bin\Debug\b_FirstService.dll". Зайдите в службу в этом же окне и выберите имя службы как "b_FirstService.WorkBook".

Нажмите "Open" и вы увидите, что имя службы сменится.

Теперь необходимо указать используемый сервисный контракт. Для этого перейдите по иерархическому списку в "Services" : "b_FirstService.WorkBook" : "Endpoints" (Конечные точки): "(Empty Name)". Как можно увидеть, для нашей службы уже созданы две конечных точки. Одна с привязкой (binding) basicHttpBinding, а другая с mexHttpBinding. У второй точки есть адрес "mex", у первой точки такого адреса нет.

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

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

Далее кнопка "…", потом нужно найти библиотеку службы и в ней выбрать единственный контракт "b_FirstService.IWorkBook". Таким образом, в графе Contract службы будет установлено значение b_FirstService.IWorkBook.

Этого достаточно для запуска и тестирования службы. Сохраните конфигурационные настройки и закройте редактор конфигураций.

3. Запуск и тестирование службы

Перейдите в проект и выберите в меню "Отладка" : "Начать отладку" (или "Запуск без отладки"). Visual Studio разместит службу в тестовом приложении и запустит тестовый клиент. Перед вами откроется такое окно:

На экране могут появиться дополнительные функции для асинхронного взаимодействия (помеченные как Async), можете их пока игнорировать.

Перед тем как работать со службой, посмотрим, где же она была размещена. В системном лотке, в правом нижнем углу экрана (около часов) должен появиться значок программы, который называется "Узел службы WCF". Двойным щелчком по иконке откройте эту программу.

В окне программы показана наша служба, ее состояние и адрес метаданных. Отметим, что значение состояния "Запущена", а адрес представляет собой:

Перейдем в окно тестового клиента службы. Окно клиента разделено на две области. Левая область называется "Мои проекты служб", правая область показывает связанное с левой содержимое. Сейчас в левой области есть только одна наша служба, которая расположена по адресу http://localhost:8731/Design_Time_Addresses/b_FirstService/Service1/mex. В этой службе есть контракт IWorkBook, который определяет 3 уже знакомых нам операции.

Сделайте двойной щелчок по операции AddBook(). Перед вами появится таблица со столбцами "Имя", "Значение", "Тип". Поля "Имя" будут заполнены нашими переменными, а вот напротив некоторых из них будут значения в виде "null". Эти значения можно заполнить и отправить службе.

Например, введите "author" как "Артамонов И.В.", comments как "Книга о распределенных системах", а name как "Распределенные системы" и нажмите "Вызвать". Перед началом вызова VisualStudio попытается предупредить о том, что мы работает через незащищенное соединение. С этим нужно согласиться, а, возможно, даже поставить флажок "Не выводить сообщения в дальнейшем".

На несколько секунд тестовый клиент WCF должен "Зависнуть", а после в нижней части экрана, в поле "Ответ", должен появиться нулевой ответ. И это верно, так как наша служба еще не умеет отвечать на запросы клиента, она может только их принимать.

Отметим, что поля "create" и "id" заполнить не удастся, вернее служба не будет сохранять то, что вы введете, так как эти значения задаются программно. Например, id задается равным значению переменной global_id.

Чтобы убрать их отображение в тестовом клиенте вам нужно, всего лишь, перейти в класс Book в среде разработки и убрать атрибуты [DataMember] для полей "create" и "id". При следующем тестировании службы эти поля уже не будут предлагаться для ввода.

Потренируйтесь с вводом разных значений для функции AddBooks() и вызовом службы.
Перейдите к функции GetBooks(). Эта функции ничего не принимает, зато, как мы помним, возвращает список сохраненных книг. Нажмите "Вызвать".

Клиент должен отобразить список всех ранее введенных книг. Например:

Аналогично вы можете протестировать функцию удаления книги из списка (функция DelBook()). Вы можете передавать службе идентификаторы книг, которые нужно удалить, и проверять, удалила ли она книги с этими номерами из списка.

Разработка клиентской части для работы со службой рассматривается в следующей статье: Основы разработки WCF-служб. Часть 4. Клиент для службы.

Размещение службы в отдельном независимом процессе рассматривается в: Основы разработки WCF-служб. Часть 5. Размещение службы в отдельном процессе.


Библиографическое описание

Артамонов, И. В. Разработка распределенных сервисно-ориентированных программных средств / Иван Васильевич Артамонов. – Иркутск : БГУЭП, 2012. – 130 с.

URL-ссылка

https://artamonoviv.ru/articles/wcf_tutorial_3/