Настройка и расширение среды выполнения с помощью поведений
Поведения позволяют изменять функциональность по умолчанию и добавлять пользовательские элементы, которые проверяют конфигурацию службы или изменяют поведение клиентских приложений и приложений служб 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 являются точками входа расширяемости для доступа к коллекциям расширения и свойствам среды выполнения клиента и службы соответственно. Аналогично классы ClientOperation и DispatchOperation предоставляют доступ к коллекциям расширения и свойствам среды выполнения операций клиента и операций службы соответственно. Однако из объекта среды выполнения операции, если это требуется, можно получить доступ к объекту среды выполнения с более широкой областью и наоборот.
Примечание |
---|
Описание типов расширения и свойств среды выполнения, с помощью которых можно изменять функциональность клиента, см. в разделе Расширение клиентов. Описание типов расширения и свойств среды выполнения, с помощью которых можно изменять функциональность диспетчера службы, см. в разделе Расширение диспетчеров. |
Большинство пользователей WCF не взаимодействуют со средой выполнения напрямую; вместо этого они используют элементы базовой модели программирования, например конечные точки, контракты, привязки, адреса и атрибуты поведений в классах или поведения в файлах конфигурации. Из этих элементов состоит дерево описания, которое представляет собой полную спецификацию для создания среды выполнения, предназначенной для поддержки службы или клиента, описываемых деревом описания.
В WCF имеется четыре типа поведений:
поведения служб (типы IServiceBehavior) позволяют настраивать среду выполнения службы целиком, включая ServiceHostBase;
поведения конечных точек (типы IEndpointBehavior) позволяют настраивать конечные точки служб и соответствующие объекты EndpointDispatcher;
поведения контрактов (типы IContractBehavior) позволяют настраивать классы ClientRuntime и DispatchRuntime в приложениях клиентов и служб соответственно;
поведения операций (типы IOperationBehavior) позволяют настраивать классы ClientOperation и DispatchOperation в приложениях клиентов и служб.
Эти поведения можно добавлять в различные объекты описания путем реализации пользовательских атрибутов, с помощью файлов конфигурации приложений или путем их непосредственного добавления в коллекцию поведений соответствующего объекта описания. Однако их обязательно необходимо добавлять в объекты описания службы или конечной точки службы до вызова метода System.ServiceModel.ICommunicationObject.Open объектов ServiceHost и ChannelFactory.
Области поведений
Каждый из четырех типов поведений соответствует определенной области доступа среды выполнения.
Поведения служб
Поведения служб, реализующие интерфейс IServiceBehavior, являются основным механизмом для изменения всей среды выполнения службы. Имеется три механизма добавления поведений служб к службам.
С помощью атрибута класса службы. При создании объекта ServiceHost реализация класса ServiceHost использует отражение, чтобы обнаружить набор атрибутов типа службы. Все атрибуты, реализующие интерфейс IServiceBehavior, добавляются в коллекцию поведений в объекте ServiceDescription. Это позволяет таким поведениям участвовать в создании среды выполнения службы.
Добавление поведения в коллекцию поведений в объекте ServiceDescription программным образом. Эту задачу можно решить с помощью следующего фрагмента кода:
ServiceHost host = new ServiceHost(/* Parameters */); host.Description.Behaviors.Add(/* Service Behavior */);
Реализация пользовательского элемента BehaviorExtensionElement, который расширяет конфигурацию. Это позволяет использовать поведение службы в файлах конфигурации приложения.
К примерам поведений служб в WCF относится атрибут ServiceBehaviorAttribute, а также поведения ServiceThrottlingBehavior и ServiceMetadataBehavior.
Поведения контрактов
Поведения контрактов, реализующие интерфейс IContractBehavior, служат для расширения сред выполнения клиента и службы в рамках контракта.
Имеется два механизма добавления поведений контрактов к контрактам. Первый механизм предполагает создание пользовательского атрибута, который будет использоваться в интерфейсе контракта. Когда интерфейс контракта передается объекту ServiceHost или ChannelFactory, среда WCF проверяет атрибуты этого интерфейса. Все атрибуты, реализующие интерфейс IContractBehavior, добавляются в коллекцию поведений в объекте System.ServiceModel.Description.ContractDescription, созданном для этого интерфейса.
Кроме того, можно реализовать интерфейс System.ServiceModel.Description.IContractBehaviorAttribute в атрибуте поведения пользовательского контракта. В этом случае поведение, если оно применяется, выглядит следующим образом.
•Интерфейс контракта. В этом случае поведение применяется ко всем контрактам этого типа в любой конечной точке, а WCF не учитывает значение свойства System.ServiceModel.Description.IContractBehaviorAttribute.TargetContract.
•Класс службы. В этом случае поведение применяется только к конечным точкам, контракт которых имеет значение, равное значению свойства TargetContract.
•Класс обратного вызова. В этом случае поведение применяется к конечной точке дуплексного клиента, а WCF не учитывает значение свойства TargetContract.
Второй механизм предполагает добавление поведения в коллекцию поведений объекта ContractDescription.
К примерам поведений контрактов в WCF относится атрибут System.ServiceModel.DeliveryRequirementsAttribute. Дополнительные сведения и пример см. в справочном разделе.
Поведения конечных точек
Поведения конечных точек, реализующие интерфейс IEndpointBehavior, являются основным механизмом для изменения всей среды выполнения службы или клиента для конкретной конечной точки.
Имеется два механизма добавления поведений конечных точек к службам.
Добавьте поведение в свойство Behaviors.
Реализуйте пользовательский элемент BehaviorExtensionElement, который расширяет конфигурацию.
Дополнительные сведения и пример см. в справочном разделе.
Поведения операций
Поведения операций, реализующие интерфейс IOperationBehavior, служат для расширения сред выполнения клиента и службы для каждой из операций.
Имеется два механизма добавления поведений операций к операциям. Первый механизм предполагает создание пользовательского атрибута, который будет использоваться в методе, моделирующем операцию. При добавлении операции в объект ServiceHost или ChannelFactory среда WCF добавляет все атрибуты IOperationBehavior в коллекцию поведений объекта OperationDescription, созданного для данной операции.
Второй механизм предполагает непосредственное добавление поведения в коллекцию поведений объекта OperationDescription.
К примерам поведений операций в WCF относятся атрибуты OperationBehaviorAttribute и TransactionFlowAttribute.
Дополнительные сведения и пример см. в справочном разделе.
Создание поведений с помощью файла конфигурации
Поведения служб, конечных точек и контрактов можно разрабатывать таким образом, чтобы задавать их в коде с помощью атрибутов. Только поведения служб и конечных точек можно настраивать с помощью файлов конфигурации приложения и веб-службы. Предоставление доступа к поведениям с помощью атрибутов позволяет разработчикам задавать поведение во время компиляции; это значит, что такое поведение нельзя добавлять, удалять или изменять во время выполнения. Этот подход часто применяется для поведений, которые обязательно нужны для правильной работы службы (например, связанные с транзакциями параметры атрибута System.ServiceModel.ServiceBehaviorAttribute). Предоставление доступа к поведениям с помощью файлов конфигурации позволяет разработчикам переложить обязанности по спецификации и настойке этих поведений на тех, кто будет развертывать службу. Такой подход удобно применять для поведений, которые являются необязательными компонентами, или для других конфигураций, которые зависят от развертывания, например, чтобы определить, нужно ли предоставлять метаданные всей службе или же только конкретной конфигурации авторизации службы.
Примечание |
---|
Также можно использовать поведения, которые поддерживают файлы конфигурации, для реализации политик применения путем их вставки в файл конфигурации machine.config и блокировки соответствующих элементов от изменений. Описание и пример см. в разделе Как блокировать конечные точки в среде предприятия. |
Чтобы сделать поведение доступным с помощью файла конфигурации, разработчик должен создать производный класс для класса BehaviorExtensionElement, а затем зарегистрировать расширение в конфигурации.
В следующем примере кода показано, каким образом интерфейс IEndpointBehavior реализует объект BehaviorExtensionElement.
Чтобы система конфигурации загрузила пользовательский объект BehaviorExtensionElement, он должен быть зарегистрирован в качестве расширения. В следующем примере кода показан файл конфигурации для предыдущего поведения конечной точки.
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.WCF.Documentation.SampleService"
behaviorConfiguration="metadataSupport"
>
<host>
<baseAddresses>
<add baseAddress="https://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 и System.ServiceModel.ServiceHost отвечают за построение среды выполнения на основе модели программирования и описания. Как было сказано выше, поведения участвуют в этом процессе, оказывая влияние на службы, конечные точки, контракты и операции.
Объект ServiceHost применяет поведения в следующем порядке.
Контракт.
Операция.
Конечная точка.
Служба.
В рамках одной коллекции поведений порядок не гарантируется.
Объект ChannelFactory применяет поведения в следующем порядке.
Контракт.
Конечная точка.
Операция.
В рамках одной коллекции поведений порядок также не гарантируется.
Добавление поведений программным образом
Свойства объекта System.ServiceModel.Description.ServiceDescription в приложении службы нельзя изменять после вызова метода System.ServiceModel.Channels.CommunicationObject.OnOpening для объекта System.ServiceModel.ServiceHostBase. Некоторые члены, например свойство System.ServiceModel.ServiceHostBase.Credentials и методы AddServiceEndpoint классов ServiceHostBase и System.ServiceModel.ServiceHost создают исключения, если их изменить на этом этапе. Другие члены можно изменять без появления исключения, но результат при этом будет неопределенным.
Аналогично на стороне клиента нельзя изменять значения System.ServiceModel.Description.ServiceEndpoint после вызова метода OnOpening для объекта System.ServiceModel.ChannelFactory. Если свойство System.ServiceModel.ChannelFactory.Credentials изменить на этом этапе, будет создано исключение. Другие значения описания клиента можно изменять без возникновения ошибки, однако результат в этом случае будет неопределенным.
Как для службы, так и для клиента, рекомендуется изменять описание до вызова метода System.ServiceModel.Channels.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.
Поведения контрактов
Для заданного контракта применяются все атрибуты поведения контракта для этого интерфейса и всех его родительских интерфейсов. Если атрибуты одного и того же типа встречаются на различных уровнях иерархии наследования, используется тип более низкого уровня иерархии.
Поведения операций
Если данная операция не переопределяет существующую абстрактную или виртуальную операцию, никакие правила наследования не применяются.
Если операция переопределяет существующую операцию, то применяются все атрибуты поведения данной операции и ее родительских операций. Если атрибуты одного и того же типа встречаются на различных уровнях иерархии наследования, используется тип более низкого уровня иерархии.