Статьи:







Рекламка:

Предупреждение

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

Краткий обзор архитектуры WCF



Краткий обзор архитектуры WCF




Корпорация Microsoft
Март 2006

Источник: MSDN
Перевод: max404.NET (, )
Версия: 0.3



Введение


Этот документ предоставляет высокоуровневое представление архитектуры Windows Communication Foundation (WCF). В нём объясняются ключевые понятия (концепции) WCF и их взаимосвязь. Также приводится несколько примеров кода, чтобы проиллюстрировать эти понятия, но этот документ не акцентируется на коде.

Остальная часть этого документа организована в двух основных разделах:
  • Основные принципы WCF: Охватывает ключевые концепции WCF, термины и архитектурные компоненты.

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



Основные принципы WCF


Сервис WCF - программа, которая предоставляет коллекцию Оконечных точек (Endpoints). Каждая Оконечная точка - портал для взаимодействия (связи) с миром.

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

Следующие разделы описывают эти основные принципы более подробно.

Оконечные точки (Endpoints)


Оконечная точка Сервиса имеет Адрес(Address), Связывание(Binding) и Контракт(Contract)

Адрес Оконечной точки - сетевой адрес её постоянного местанахождения (где). Класс EndpointAddressпредставляет Адрес Оконечной точки WCF.

Связывание Оконечной точки определяет, как Оконечная точка взаимодействует с миром, включая такие вещи как транспортный протокол (например TCP, HTTP), кодирование (например текст, двоичное), и требования к безопасности (например SSL, безопасность сообщения SOAP). Класс Binding представляет Связывание WCF.

Контракт Оконечной точки определяет то, что (чем) Оконечная точка взаимодействует, и является по существу коллекцией сообщений, организованных в операции, которые основаны на Message Exchange Patterns (MEPs); например односторонний, дуплексный, запрос/ответ. Класс ContractDescription представляет Контракт WCF.

Класс ServiceEndpoint представляет Оконечную точку и имеет EndpointAddress, Binding, и ContractDescription (Описание Контракта) как соответствие Адресу Оконечной точки, Связыванию и Контракту.


Рисунок 1. Оконечная точка каждого Сервиса содержит Адрес, Связывание и Контракт, представленный ContractDescription.



Адрес Оконечной точки (EndpointAddress)


Адрес Оконечной точки - в основном URI, Identity, и коллекция необязательных заголовков как показано на рисунке 2.

В качестве Identity безопасности Оконечной точки обычно используют её URI; однако, в усложненных сценариях identity может быть явно установлено независимым от URI с помощью свойства Identity адреса.

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


Рисунок 2. Адрес Оконечной точки содержит URI, Identity и коллекцию AddressHeaders.



Связывания (Bindings)


Связывание имеет имя, пространство имен, и коллекцию компонуемых элементов связывания (рисунок 3). Имя Связывания и пространство имен однозначно определяют его в метаданных сервиса. Каждый элемент связывания описывает аспект того, как Оконечная точка контактирует с миром.


Рисунок 3. Класс Связывание и его члены



На рисунке 4 приведен пример коллекции, содержащей три элемента связывания. Присутствие каждого элемента связывания описывает часть того, как осуществляется взаимодействие с Оконечной точкой. TcpTransportBindingElement указывает, что Оконечная точка осуществляет связь, используя TCP как транспортный протокол. ReliableSessionBindingElement указывает, что Оконечная точка использует надежную передачу сообщений, чтобы предоставить гарантии доставки сообщения. SecurityBindingElement указывает, что Оконечная точка использует безопасность сообщения SOAP. Каждый элемент связывания обычно имеет свойства, которые детализируют специфику коммуникации с Оконечной точкой. Например, ReliableSessionBindingElement имеет свойство Assurances, которое определяет необходимые гарантии доставки сообщения, а именно: никаких, по крайней мере однажды, не более чем однажды, точно однажды.


Рисунок 4. Пример Связывания с тремя элементами связывания



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

Контракты


Контракт WCF - коллекция Операций (Operations), которая определяет то, что Оконечная точка сообщает внешнему миру. Каждая операция - простой обмен сообщением, например односторонний или обмен сообщением запроса/ответа.

Класс ContractDescription используется, чтобы описать Контракты WCF и их операции. В ContractDescription, каждая операция Contract имеет соответствующий OperationDescription, который описывает аспекты операции, например, является ли операция односторонней или типа запрос/ответ. Каждый OperationDescription также описывает сообщения, которые составляют операцию, используя коллекцию, содержащую MessageDescription-ы.

ContractDescription обычно создается из интерфейса или класса, который определяет Контракт, используя модель программирования WCF. Этот тип аннотируется атрибутом ServiceContractAttribute, а методы, которые соответствуют Операциям Оконечной точки, аннотируются атрибутом OperationContractAttribute. Вы можете также сформировать ContractDescription вручную, не начиная с CLR-типа, аннотированного атрибутами.

Дуплексный Контракт определяет два логических набора операций: набор операций Сервиса, предоставляемых для вызова Клиентом, и набор, который Клиент предоставляет для вызова Сервисом. Модель программирования для определения дуплексного Контракта должна разбить каждый набор на отдельный тип (каждый тип должен быть классом или интерфейсом), и аннотировать контракт, который представляет операции сервиса атрибутом ServiceContractAttribute, ссылаясь на контракт, который определяет операции клиента (или обратный вызов). Кроме того, ContractDescription содержит ссылку на каждый из типов, таким образом группируя их в один дуплексный Контракт.

Подобно Связываниям, каждый Контракт имеет Имя (Name) и Пространство имен (Namespace), которые однозначно определяют его в метаданных Сервиса.

Каждый Контракт также имеет коллекцию, содержащую ContractBehaviors, которые являются модулями, изменяющими или расширяющими поведение контракта. Следующий раздел охватывает поведения более подробно.


Рисунок 5. Класс ContractDescription описывает контракт WCF



Поведения


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

Поведения также участвуют в процессе формирования канала и могут изменять его, основываясь на указанных пользователем параметрах настройки и/или других аспектах Сервиса или Канала.

Поведение Сервиса - тип, который реализует IServiceBehavior и применяется к Сервисам. Точно так же Поведение Канала (Channel Behavior) - тип, который реализует IChannelBehavior и применяется к Клиентским Каналам.

Описания Сервиса и Канала


Класс ServiceDescription - структура данных в памяти, которая описывает Сервис WCF, включая Оконечные точки, предоставленные Сервисом, Поведения применяемые к Сервису, и тип (класс), который реализует Сервис (см. рисунок 6). ServiceDescription используется, чтобы создать метаданные, код/конфигурацию, и каналы.

Вы можете сформировать этот объект ServiceDescription вручную. Вы можете также создать его из типа, аннотированного определенными атрибутами WCF, что является более общим сценарием. Код для этого типа может писаться вручную или сгенерирован из документа WSDL с помощью инструмента WCF, называемого svcutil.exe.

Хотя объекты ServiceDescription могут быть созданы и заполнены явно, они часто создаются автоматически как часть выполнения Сервиса.


Рисунок 6. Объектная модель ServiceDescription



Подобно и на клиентской стороне, ChannelDescription описывает Клиентский Канал WCF конкретной Оконечной точки (рисунок 7). Класс ChannelDescription имеет коллекцию IChannelBehaviors, которые являются Поведениями, которые применяются на Канале. Он также имеет ServiceEndpoint, который описывает Оконечную точку, с которой Канал осуществляет связь.

Обратите внимание, что, в отличие от ServiceDescription, ChannelDescription содержит только один ServiceEndpoint, который представляет целевую Оконечную точку, с которой осуществляет связь Канал.


Рисунок 7. Объектная модель ChannelDescription



Среда выполнения WCF (WCF Runtime)


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

Сообщение


Сообщение WCF - модуль обмена данными между Клиентом и Оконечной точкой. Сообщение - по существу представление в оперативной памяти сообщения SOAP InfoSet. Обратите внимание, что Сообщение не привязано к текстовому XML. Более того, в зависимости от используемого механизма кодирования, Сообщение можно сериализовать, используя двоичный формат WCF, текстовый XML, или любой другой пользовательский формат.

Каналы


Каналы - основная абстракция для отправки и получения Сообщения от Оконечной точки. Вообще говоря, есть две категории Каналов: Транспортные Каналы, обрабатывающие отправку или получение непрозрачных октет потоков, используя некоторую форму транспортного протокола, например, TCP, UDP, или MSMQ. Протокольные Каналы, с другой стороны, реализуют протокол на основе SOAP, обрабатывая и возможно изменяя сообщения. Например, Канал безопасности добавляет и обрабатывает заголовки сообщения SOAP и может изменить тело сообщения, зашифровав его. Каналы компонуются так, что Канал может быть наслоен поверх другого Канала, который в свою очередь наслоен поверх третьего Канала.

EndpointListener


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

ServiceHost и ChannelFactory


Среда выполнения Сервиса WCF обычно создается автоматически (за сценой), вызовом ServiceHost.Open(). ServiceHost (рисунок 6) управляет созданием ServiceDescription на основе типа Сервиса и заполняет коллекцию ServiceEndpoint ServiceDescription-а Оконечными точками, определенными в конфигурации/коде, или и то и другое. ServiceHost использует ServiceDescription, чтобы создать стек канала в форме объекта EndpointListener для каждого ServiceEndpoint в ServiceDescription.


Рисунок 8. Объектная модель ServiceHost



Точно так же на клиентской стороне, Клиентская среда выполнения создается ChannelFactory, который является Клиентским эквивалентом ServiceHost.

ChannelFactory управляет созданием ChannelDescription основанного на типе Контракта, Связывании, и EndpointAddress. Затем он использует этот ChannelDescription, чтобы создать Клиентский стек канала.

В отличие от среды выполнения Сервиса, Клиентская среда выполнения не содержит EndpointListeners, потому что Клиент всегда инициализирует подключение(связь) с Сервисом, таким образом нет никакой потребности "слушать" входящие подключения.

Примеры кода


Этот раздел предоставляет примеры кода, которые показывают, как формируются Сервисы и Клиенты. Эти примеры предназначены для того, чтобы овеществить вышеупомянутые понятия(концепции), а не обучить программированию WCF.

Определение и Реализация Контракта


Как упомянуто выше, самый простой способ определить контракт это создать интерфейс или класс и аннотировать его атрибутом ServiceContractAttribute, позволяя системе легко создать из него ContractDescription.

При использовании интерфейсов или классов для определения контрактов, каждый интерфейс или метод класса, который является членом контракта, должен аннотироваться атрибутом OperationContractAttribute. Например:
using System.ServiceModel;

//a WCF contract defined using an interface

[ServiceContract]
public interface IMath
{
    [OperationContract]
    int Add(int x, int y);
}


Реализация контракта в этом случае - просто вопрос создания класса, который реализует IMath. Этот класс становится классом Сервиса WCF. Например:
//the service class implements the interface

public class MathService : IMath
{
    public int Add(int x, int y)
    { return x + y; }
}


Определение Оконечных точек и Запуск Сервиса


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

Метод DefineEndpointInConfig показывает эквивалентную оконечную точку, определенную в конфигурации (пример конфигурации следует за кодом).
public class WCFServiceApp
{
    public void DefineEndpointImperatively()
    {
        //create a service host for MathService

        ServiceHost sh = new ServiceHost(typeof(MathService));

        //use the AddEndpoint helper method to

        //create the ServiceEndpoint and add it 

        //to the ServiceDescription

        sh.AddServiceEndpoint(
          typeof(IMath), //contract type

          new WSHttpBinding(), //one of the built-in bindings

          "http://localhost/MathService/Ep1"); //the endpoint's address


        //create and open the service runtime

        sh.Open();
    }

    public void DefineEndpointInConfig()
    {
        //create a service host for MathService

        ServiceHost sh = new ServiceHost (typeof(MathService));

        //create and open the service runtime

        sh.Open();
    }
}


<!-- configuration file used by above code -->
<configuration 
   xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
   <system.serviceModel>
      <services>
                 <!-- service element references the service type -->
         <service type="MathService">
            <!-- endpoint element defines the ABC's of the endpoint -->
              <endpoint 
            address="http://localhost/MathService/Ep1"
            binding="wsHttpBinding"
              contract="IMath"/>
         </service>
      </services>
   </system.serviceModel>
</configuration>



Отправка Сообщений Оконечной точке


Код ниже показывает два способа отправить сообщение оконечной точке IMath. SendMessageToEndpoint скрывает создание Канала, которое происходит автоматически, в то время как пример SendMessageToEndpointUsingChannel делает это явно.

Первый пример в SendMessageToEndpoint использует инструментальное средство - svcutil.exe и метаданные Сервиса, чтобы генерировать Контракт (IMath в этом примере), прокси-класс (MathProxy в этом примере), который реализует Контракт, и связанную конфигурацию (не показанную здесь). Снова, Контракт, определенный IMath специфицирует что (то есть, операции, которые могут быть выполнены), в то время как сгенерированная конфигурация содержит Связывание (как) и адрес (где).

Использование этого прокси-класса - просто вопрос создания его экземпляра и вызова метода Add. За сценой прокси-класс создаст Канал и использует его для коммуникации с Оконечной точкой.

Второй пример в SendMessageToEndpointsUsingChannel ниже показывает коммуникацию с Оконечной точкой, непосредственно используя ChannelFactory. В этом примере, вместо того, чтобы использовать прокси-класс и конфигурацию, Канал создается непосредственно, используя ChannelFactory<IMath>.CreateChannel(). Также, вместо того, чтобы использовать конфигурацию для определения адреса Оконечной точки и Связывания, конструктор ChannelFactory<IMath> принимает это две порции информации как параметры. Третья порция информации, требуемая для определения Оконечной точки, а именно Контракт, передается как тип T.
using System.ServiceModel;
//this contract is generated by svcutil.exe

//from the service's metadata

public interface IMath
{
    [OperationContract]
    public int Add(int x, int y)
    { return x + y; }
}


//this class is generated by svcutil.exe

//from the service's metadata

//generated config is not shown here

public class MathProxy : IMath
{
    ...
}

public class WCFClientApp
{
    public void SendMessageToEndpoint()
    {
        //this uses a proxy class that was

        //created by svcutil.exe from the service's metadata

        MathProxy proxy = new MathProxy();

        int result = proxy.Add(35, 7);
    }
    public void SendMessageToEndpointUsingChannel()
    {
        //this uses ChannelFactory to create the channel

        //you must specify the address, the binding and 

        //the contract type (IMath)

        ChannelFactory<IMath> factory=new ChannelFactory<IMath>(
            new WSHttpBinding(),
            new EndpointAddress("http://localhost/MathService/Ep1"));
        IMath channel=factory.CreateChannel();
        int result=channel.Add(35,7);
        factory.Close();
    }
}



Определение собственного (заказного) Поведения


Определение собственного Поведения - вопрос реализации IServiceBehavior (или IChannelBehavior для клиентских поведений). Код ниже показывает приведенное в качестве примера поведение, которое реализует IServiceBehavior. В IServiceBehavior.ApplyBehavior, код осматривает ServiceDescription и выписывает Адрес, Связывание, и Контракт каждого ServiceEndpoint, а также имени каждого Поведения в ServiceDescription.

Это специфическое поведение также является атрибутом (наследуется от System.Attribute), что позволяет применять его декларативно, как будет показано ниже. Однако, поведения не обязаны быть атрибутами.
[AttributeUsageAttribute(AttributeTargets.Class,
         AllowMultiple=false,
         Inherited=false)]
public class InspectorBehavior : System.Attribute, 
                                 System.ServiceModel.IServiceBehavior
{
   public void ApplyBehavior(ServiceDescription description,
       Collection<DispatchBehavior> behaviors)
   {
       Console.WriteLine("-------- Endpoints ---------");
       foreach (ServiceEndpoint endpoint in description.Endpoints)
       {
           Console.WriteLine("--> Endpoint");
           Console.WriteLine("Endpoint Address: {0}", 
                             endpoint.Address);
           Console.WriteLine("Endpoint Binding: {0}", 
                             endpoint.Binding.GetType().Name);
           Console.WriteLine("Endpoint Contract: {0}", 
                              endpoint.Contract.ContractType.Name);
           Console.WriteLine();
       }
       Console.WriteLine("-------- Service Behaviors --------");
       foreach (IServiceBehavior behavior in description.Behaviors)
       {
           Console.WriteLine("--> Behavior");
           Console.WriteLine("Behavior: {0}", behavior.GetType().Name);
           Console.WriteLine();
       }
   }
}


Применение собственного Поведения


Все поведения могут быть применены императивно, добавлением экземпляра поведения к ServiceDescription (или ChannelDescription на клиентской стороне). Например, чтобы применить InspectorBehavior императивно, Вы написали бы:
ServiceHost sh = new ServiceHost(typeof(MathService));
sh.AddServiceEndpoint(typeof(IMath),
        new WSHttpBinding(),
       "http://localhost/MathService/Ep1"); 
//Add the behavior imperatively

InspectorBehavior behavior = new InspectorBehavior();
sh.Description.Behaviors.Add(behavior);
sh.Open();


Кроме того, поведения, которые унаследованы от System.Attribute могут быть применены декларативно к сервису. Например, ввиду того, что InspectorBehavior унаследован от System.Attribute, он может быть применен декларативно:
[InspectorBehavior]
public class MathService : IMath
{
   public int Add(int x, int y)
   { return x + y; }
}


Summary


Сервисы WCF предоставляют коллекцию Оконечных точек, где каждая Оконечная точка - портал для коммуникации с миром. Каждая Оконечная точка имеет Адрес, Связывание, и Контракт (ABC). Адрес определяет где Оконечная точка постоянно находится, Связывание состоит в том, как Оконечная точка поддерживает связь, и Контракт - то, что сообщает Оконечная точка.

В Сервисе, ServiceDescription хранит коллекцию с ServiceEndpoint-ами - описание каждой Оконечной точки, которую Сервис предоставляет. Из этого описания ServiceHost создает среду выполнения, которая содержит EndpointListener для каждого ServiceEndpoint в ServiceDescription. Адрес Оконечной точки, Связывание, и Контракт (представляющий где, что и как) соответствуют адресу прослушивания EndpointListener-а, фильтрации и диспетчеризации сообщения, и стеку канала соответственно.

Точно так же на Клиенте, ChannelDescription хранит один ServiceEndpoint, с которым поддерживает связь Клиент. Из этого ChannelDescription, ChannelFactory создает стек канала, который может взаимодействовать с Оконечной точкой Сервиса.
Идентификатор статьи: 58
Дата занесения/обновления: 01.10.2006 10:15

Комментарии к статье

Вы можете добавить свой комментарий или посмотреть отзывы других посетителей сайта (1)
Имя:
Текст:
  mml?
Пожалуйста, подтвердите, что вы человек, введя значение выражения 102+82=