В нашей жизни Мы постоянно подписываем разные договора — будь то догово про аренду, приему на работу, покупки машини, или брачный контракт:) Чтобы небыло недопониманий контракт должен четко прописывать обязанности каждой из сторон , чтобы в будущем было как можно менише вещей для обсуждения.
Соственно в архитектуре ориентированной на использование сервисов, где разные комманды могут писать разные сервиса, при чем даже на разных технологиях — четкое описание как какой сервис может взаимодействовать с другим сервисом — просто необходимо!
Технология WCF построенна на концепции контрактов, с помощью которых мы можем описать взаимодействия между сервисами, формат сообщений, и т.д. Эта технология предлагает нам три разных типа контрактов: контракт сообщений, данных и сервисов.
Контракт сервисов — определяет как сервис будет взаимодействовать с внешним миром.
Контракт данных — определяет формат данных которыми сервисы буду обмениваться. Это относится как к запросу на сервис, так и к овтету сервиса. Если вы используете примитивные типы, вроде int, string,etc. то контракт не нужен, потому как .Net прекрасно понимает как серилизовать и десерилизовать типы, но если вы используете более комплексные типы, вроде Customers, Order, etc. Вам нужно сказать как серилизовать и десерилизовать эти объекты.
Контракт сообщений — этот тип контракта, который используется для того чтобы получить больший контроль над заголовками SOAP пакета.
Создание котрактов! Наконец код!
Так как мы уже говорили , перед началом разработки — интерефейсы должны быть попределенны , и меняться они должны только в самых краиних случаях, давайте создадим интерфейс для нашего первого сервиса!
Для тестовых целей, я создал обычное консольное приложение. Чтобы описать контракт давайте добавим к нашиму солюшену библиотеку классов, в которой добавим вот такой интерфейс:
[ServiceContract()] public interface ICalculatorService { [OperationContract()] int Add(int a, int b); [OperationContract()] int Multiply(int a, int b); [OperationContract()] int Divide(int a, int b); [OperationContract()] int Substract(int a, int b); }
Как видим, Мы создали интерфейс для сервиса — калькулятора ( как неожиданно, правда?:)) . Интерефейс обозначен аттрибутом: ServiceContract(), для всех методов этого сервиса мы использовали аттрибут: OperationContract().
Теперь давайте добавим реализацию нашего сервиса. Для этого создадим новый тип проекта WCF Application:
Как мы видим в нашем солюшене создался новый проект, который уже содержит пример реализации WCF сервиса. Удаляем его:)
Теперь добавим ссылку на наш проект с интерефейсами и откроем cs файл. Введем такой текст:
public class CalculatorService: ICalculatorService { public int Add(int a, int b) { return a + b; } public int Multiply(int a, int b) { return a * b; } public int Divide(int a, int b) { return a / b; } public int Substract(int a, int b) { return a - b; } }
Собственно это и все, наш темповый сервис готов!:) Теперь давайте добавим ссылку на него в нашей консольной аппликации.
После того как мы добавим ссылку на сервис — мы можем увидеть что создался конфигурационный файл app.config. Там аддресс сервиса, по которому к нему можна обращаться. Мы рассмотрим конфигурационный файл несколько позже. А пока, давайте портестируем работу нашего сервиса!
В результате у нас должно получится что то вроде этого:
class Program { static void Main(string[] args) { CalculatorService.CalculatorServiceClient client = new CalculatorService.CalculatorServiceClient(); Console.WriteLine("Adding: 10 + 2 = {0}", client.Add(10, 2)); Console.WriteLine("Multiply: 10 * 2 = {0}", client.Multiply(10, 2)); Console.WriteLine("Divide: 10 / 2 = {0}", client.Divide(10, 2)); Console.WriteLine("Substract: 10 - 2 = {0}", client.Substract(10, 2)); } }
Если все сделанно правильно, то ответ будет таков:
Adding: 10 + 2 = 12
Multiply: 10 * 2 = 20
Divide: 10 / 2 = 5
Substract: 10 — 2 = 8
Вроде и все работает, но WSDL который сгенерил сервис иногда нуждается в дополнительных улучшениях.
Мы можем повлиять на генерацию WSDL с помощью аттрибутов которые мы можем выставтлять в классе с интерфейсом нашего сервиса. Давайте немного поменяем наш интерфейс сервиса:
[ServiceContract( Namespace="http://coolestCalcService", Name = "SuperMathCalc")] public interface ICalculatorService { [OperationContract( Name = "AddingOperation" )] int Add(int a, int b); [OperationContract( Name = "MultiplyOperation")] int Multiply(int a, int b); [OperationContract( Name = "DivideOperation")] int Divide(int a, int b); [OperationContract( Name = "SubsractOperation")] int Substract(int a, int b); }
Теперь давайте обновим ссылку на наш сервис, и вы увидите, что как название сервиса, так и даже название операций поменялось. Теперь наша тестовая программа будет иметь такой вид:
class Program { static void Main(string[] args) { CalculatorService.SuperMathCalcClient client = new CalculatorService.SuperMathCalcClient(); Console.WriteLine("Adding: 10 + 2 = {0}", client.AddingOperation(10, 2)); Console.WriteLine("Multiply: 10 * 2 = {0}", client.MultiplyOperation(10, 2)); Console.WriteLine("Divide: 10 / 2 = {0}", client.DivideOperation(10, 2)); Console.WriteLine("Substract: 10 - 2 = {0}", client.SubsractOperation(10, 2)); } }
Все это происходит, потому что проксикласс который генерится — строится на основе WSDL сервиса.
Как мы видим — контракты сервисов помогают нам управлять WSDL структурой нашего сервиса, при этом влияя на клиентов которые будут его использовать.
Дополнительная информация по ServiceContact находится здесь:
http://msdn.microsoft.com/en-us/library/ms729746.aspx
Уведомление: Некоторые интересные ссылки (Март) | Александр Богатырев: сфера
Уведомление: ??????????? ????????? ?? ????????? ? ???????? Microsoft ?? ??????? ????? – ?????? 2011 - MSDN Blogs
Не понятно только в одном месте: чем в данном случае приложение от библиотеки отличается? Я имею ввиду создаваемые проекты в VS
НравитсяНравится
Библиотеки исполняются на твоем компе. То есть подключив библиотеку и вызвав из нее функцию, она будет обрабатываться твоими ресурсами, на твоем компе. А с WSDL дернув метод сервиса на клиенте ты пошлешь запрос на него, где бы он ни был (при правильных настройках адреса и тп). Он ТАМ у сабя обработает функцию и вернет тебе результат. Удобно для написания сервера для чего-либо.
НравитсяНравится
Хорошая статья, продолжаю читать..
Единственное, что напрягает глаз, это транслитерация английских слов(«аппликация», «версионирование»), как мне кажется можно было бы найти более удачную замену в русском языке.
А в целом отлично! Читаю дальше…
НравитсяНравится
Есть такое, но просто когда муза приходит, тяжко думать нат более точными переводами.
НравитсяНравится