Настройка и расширение среды выполнения с помощью поведений

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

Поведение

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

Методы поведений

У всех поведений имеется метод AddBindingParameters, метод ApplyDispatchBehavior, метод Validate и метод ApplyClientBehavior за единственным исключением: поскольку интерфейс IServiceBehavior не может выполняться на клиенте, он не реализует метод ApplyClientBehavior.

  • Метод AddBindingParameters служит для изменения или добавления пользовательских объектов в коллекцию, к которой могут общаться пользовательские привязки при создании среды выполнения. Например, с помощью этого метода можно задать требования защиты, которые влияют на способ создания канала, но не известны разработчику канала.

  • Метод Validate служит для проверки дерева описания и соответствующего объекта среды выполнения, чтобы убедиться, что они соответствуют определенному набору условий.

  • Методы ApplyDispatchBehavior и ApplyClientBehavior служат для проверки дерева описания и изменения среды выполнения в определенной области (на стороне службы или на стороне клиента соответственно). Кроме того, эти методы позволяют вставлять объекты расширения.

    Примечание.

    Хотя эти методы получают дерево описания, оно доступно им только для проверки. Если изменить дерево описания, поведение станет неопределенным.

Доступ к свойствам, которые можно изменить, и к интерфейсам настройки, которые можно реализовать, осуществляется через классы среды выполнения службы и клиента. Типы служб — это DispatchRuntime классы и DispatchOperation классы. Типами клиента являются классы ClientRuntime и ClientOperation. Классы ClientRuntime и DispatchRuntime являются точками входа расширяемости для доступа к коллекциям расширения и свойствам среды выполнения клиента и службы соответственно. Аналогичным образом, ClientOperationDispatchOperation классы предоставляют свойства среды выполнения операций клиента и операции обслуживания и коллекции расширений соответственно. Однако из объекта среды выполнения операции, если это требуется, можно получить доступ к объекту среды выполнения с более широкой областью и наоборот.

Примечание.

Обсуждение свойств среды выполнения и типов расширений, которые можно использовать для изменения поведения выполнения клиента, см. в разделе "Расширение клиентов". Обсуждение свойств среды выполнения и типов расширений, которые можно использовать для изменения поведения выполнения диспетчера служб, см. в разделе "Расширение диспетчеров".

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

Существует четыре типа поведения в WCF:

  • поведения служб (типы IServiceBehavior) позволяют настраивать среду выполнения службы целиком, включая ServiceHostBase;

  • поведения конечных точек (типы IEndpointBehavior) позволяют настраивать конечные точки служб и соответствующие объекты EndpointDispatcher;

  • поведения контрактов (типы IContractBehavior) позволяют настраивать классы ClientRuntime и DispatchRuntime в приложениях клиентов и служб соответственно;

  • поведения операций (типы IOperationBehavior) позволяют настраивать классы ClientOperation и DispatchOperation в приложениях клиентов и служб.

Эти поведения можно добавлять в различные объекты описания путем реализации пользовательских атрибутов, с помощью файлов конфигурации приложений или путем их непосредственного добавления в коллекцию поведений соответствующего объекта описания. Однако их обязательно необходимо добавлять в объекты описания службы или конечной точки службы до вызова метода ICommunicationObject.Open объектов ServiceHost и ChannelFactory<TChannel>.

Области поведений

Каждый из четырех типов поведений соответствует определенной области доступа среды выполнения.

Поведения служб

Поведения служб, реализующие интерфейс IServiceBehavior, являются основным механизмом для изменения всей среды выполнения службы. Имеется три механизма добавления поведений служб к службам.

  1. С помощью атрибута класса службы. При создании объекта ServiceHost реализация класса ServiceHost использует отражение, чтобы обнаружить набор атрибутов типа службы. Все атрибуты, реализующие интерфейс IServiceBehavior, добавляются в коллекцию поведений в объекте ServiceDescription. Это позволяет таким поведениям участвовать в создании среды выполнения службы.

  2. Добавление поведения в коллекцию поведений в объекте ServiceDescription программным образом. Эту задачу можно решить с помощью следующего фрагмента кода:

    ServiceHost host = new ServiceHost(/* Parameters */);  
    host.Description.Behaviors.Add(/* Service Behavior */);  
    
  3. Реализация пользовательского элемента BehaviorExtensionElement, который расширяет конфигурацию. Это позволяет использовать поведение службы в файлах конфигурации приложения.

Примеры поведения служб в WCF включают ServiceBehaviorAttribute атрибут, ServiceThrottlingBehaviorповедение и ServiceMetadataBehavior поведение.

Поведения контрактов

Поведения контрактов, реализующие интерфейс IContractBehavior, служат для расширения сред выполнения клиента и службы в рамках контракта.

Имеется два механизма добавления поведений контрактов к контрактам. Первый механизм предполагает создание пользовательского атрибута, который будет использоваться в интерфейсе контракта. При передаче интерфейса контракта в интерфейс ServiceHostChannelFactory<TChannel>WCF проверяет атрибуты. Все атрибуты, реализующие интерфейс IContractBehavior, добавляются в коллекцию поведений в объекте System.ServiceModel.Description.ContractDescription, созданном для этого интерфейса.

Кроме того, можно реализовать интерфейс System.ServiceModel.Description.IContractBehaviorAttribute в атрибуте поведения пользовательского контракта. В этом случае поведение, если оно применяется, выглядит следующим образом:

•Интерфейс контракта. В этом случае поведение применяется ко всем контрактам этого типа в любой конечной точке и WCF игнорирует значение IContractBehaviorAttribute.TargetContract свойства.

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

•Класс обратного вызова. В этом случае поведение применяется к конечной точке дуплексного клиента, и WCF игнорирует значение TargetContract свойства.

Второй механизм предполагает добавление поведения в коллекцию поведений объекта ContractDescription.

Примеры поведения контракта в WCF включают System.ServiceModel.DeliveryRequirementsAttribute атрибут. Дополнительные сведения и пример см. в справочном разделе.

Поведения конечных точек

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

Имеется два механизма добавления поведений конечных точек к службам.

  1. Добавьте поведение в свойство Behaviors.

  2. Реализуйте пользовательский элемент BehaviorExtensionElement, который расширяет конфигурацию.

Дополнительные сведения и пример см. в справочном разделе.

Поведения операций

Поведения операций, реализующие интерфейс IOperationBehavior, служат для расширения сред выполнения клиента и службы для каждой из операций.

Имеется два механизма добавления поведений операций к операциям. Первый механизм предполагает создание пользовательского атрибута, который будет использоваться в методе, моделирующем операцию. При добавлении операции в приложение ServiceHostChannelFactoryWCF добавляет любые IOperationBehavior атрибуты в коллекцию поведения, созданной OperationDescription для этой операции.

Второй механизм предполагает непосредственное добавление поведения в коллекцию поведений объекта OperationDescription.

Примеры поведения операций в WCF включают OperationBehaviorAttribute и TransactionFlowAttribute.

Дополнительные сведения и пример см. в справочном разделе.

Создание поведений с помощью файла конфигурации

Поведения служб, конечных точек и контрактов можно разрабатывать таким образом, чтобы задавать их в коде с помощью атрибутов. Только поведения служб и конечных точек можно настраивать с помощью файлов конфигурации приложения и веб-службы. Отображение поведения с помощью атрибутов позволяет разработчикам указывать поведение во время компиляции, которое невозможно добавить, удалить или изменить во время выполнения. Этот подход часто применяется для поведений, которые обязательно нужны для правильной работы службы (например, связанные с транзакциями параметры атрибута System.ServiceModel.ServiceBehaviorAttribute). Предоставление доступа к поведениям с помощью файлов конфигурации позволяет разработчикам переложить обязанности по спецификации и настойке этих поведений на тех, кто будет развертывать службу. Такой подход удобно применять для поведений, которые являются необязательными компонентами, или для других конфигураций, которые зависят от развертывания, например, чтобы определить, нужно ли предоставлять метаданные всей службе или же только конкретной конфигурации авторизации службы.

Примечание.

Также можно использовать поведения, которые поддерживают файлы конфигурации, для реализации политик применения путем их вставки в файл конфигурации machine.config и блокировки соответствующих элементов от изменений. Описание и пример см. в статье "Практическое руководство. Блокировка конечных точек в организации".

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

В следующем примере кода показано, как IEndpointBehavior реализуется BehaviorExtensionElement:

// BehaviorExtensionElement members  
public override Type BehaviorType  
{  
  get { return typeof(EndpointBehaviorMessageInspector); }  
}  
  
protected override object CreateBehavior()  
{  
  return new EndpointBehaviorMessageInspector();  
}  

Чтобы система конфигурации загрузила пользовательский объект BehaviorExtensionElement, он должен быть зарегистрирован в качестве расширения. В следующем примере кода показан файл конфигурации для предыдущего поведения конечной точки.

<configuration>  
  <system.serviceModel>  
    <services>  
      <service
        name="Microsoft.WCF.Documentation.SampleService"  
        behaviorConfiguration="metadataSupport"  
      >  
        <host>  
          <baseAddresses>  
            <add baseAddress="http://localhost:8080/ServiceMetadata" />  
          </baseAddresses>  
        </host>  
        <endpoint  
          address="/SampleService"  
          binding="wsHttpBinding"  
          behaviorConfiguration="withMessageInspector"
          contract="Microsoft.WCF.Documentation.ISampleService"  
        />  
        <endpoint  
           address="mex"  
           binding="mexHttpBinding"  
           contract="IMetadataExchange"  
        />  
      </service>  
    </services>  
    <behaviors>  
      <serviceBehaviors>  
      <behavior name="metadataSupport">  
        <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>  
      </behavior>  
      </serviceBehaviors>  
      <endpointBehaviors>  
        <behavior name="withMessageInspector">  
          <endpointMessageInspector />  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    <extensions>  
      <behaviorExtensions>  
        <add
          name="endpointMessageInspector"  
          type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"  
        />  
      </behaviorExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

Где Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector используется тип расширения поведения и HostApplication имя сборки, в которую был скомпилирован этот класс.

Порядок вычисления

Классы System.ServiceModel.ChannelFactory<TChannel> и System.ServiceModel.ServiceHost отвечают за построение среды выполнения на основе модели программирования и описания. Как было сказано выше, поведения участвуют в этом процессе, оказывая влияние на службы, конечные точки, контракты и операции.

Объект ServiceHost применяет поведения в следующем порядке.

  1. Service

  2. Contract

  3. Конечная точка

  4. Операция

В рамках одной коллекции поведений порядок не гарантируется.

Объект ChannelFactory<TChannel> применяет поведения в следующем порядке.

  1. Contract

  2. Конечная точка

  3. Операция

В рамках одной коллекции поведений порядок также не гарантируется.

Добавление поведений программным образом

Свойства объекта System.ServiceModel.Description.ServiceDescription в приложении службы нельзя изменять после вызова метода CommunicationObject.OnOpening для объекта System.ServiceModel.ServiceHostBase. Некоторые члены, например свойство ServiceHostBase.Credentials и методы AddServiceEndpoint классов ServiceHostBase и System.ServiceModel.ServiceHost создают исключения, если их изменить на этом этапе. Другие члены можно изменять без появления исключения, но результат при этом будет неопределенным.

Аналогично, на стороне клиента нельзя изменять значения System.ServiceModel.Description.ServiceEndpoint после вызова метода OnOpening для объекта System.ServiceModel.ChannelFactory. Если свойство ChannelFactory.Credentials изменить на этом этапе, будет создано исключение. Другие значения описания клиента можно изменять без возникновения ошибки, однако результат в этом случае будет неопределенным.

Как для службы, так и для клиента, рекомендуется изменять описание до вызова метода CommunicationObject.Open.

Правила наследования атрибутов поведений

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

На верхнем уровне действует следующее правило: для конкретной области (например, для службы, контракта или операции) применяются все атрибуты поведений в иерархии наследования для данной области. Если имеется два атрибута поведений одного типа, используется тип более низкого уровня иерархии.

Поведения служб

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

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]  
[AspNetCompatibilityRequirementsAttribute(  
    AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
public class A { /* … */ }  
  
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
public class B : A { /* … */}  

В приведенном выше примере у службы B атрибут InstanceContextMode имеет значение Single, атрибут AspNetCompatibilityRequirementsMode - значение Allowed, а атрибут ConcurrencyMode - значение Single. Атрибут ConcurrencyMode будет равняться Single, потому что атрибут ServiceBehaviorAttribute службы B расположен на более низком уровне иерархии по сравнению со службой A.

Поведения контрактов

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

Поведения операций

Если данная операция не переопределяет существующую абстрактную или виртуальную операцию, никакие правила наследования не применяются.

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