Расширение диспетчеров

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

В этом разделе описывается, как использовать DispatchRuntime и DispatchOperation классы в приложении службы Windows Communication Foundation (WCF) для изменения поведения выполнения по умолчанию диспетчера или перехвата или изменения сообщений, параметров или возвращаемых значений до отправки или последующего их отправки или извлечения из уровня канала. Дополнительные сведения о эквивалентной обработке сообщений среды выполнения клиента см. в разделе "Расширение клиентов". Сведения о роли, IExtensibleObject<T> которую типы играют в доступе к общему состоянию между различными объектами настройки среды выполнения, см. в разделе "Расширяемые объекты".

Диспетчеры

Уровень модели службы осуществляет преобразование между моделью программирования разработчика и базовым обменом сообщениями, который обычно называется "уровень каналов". В WCF диспетчеры каналов и конечных точек (ChannelDispatcher и EndpointDispatcherсоответственно) являются компонентами службы, ответственными за прием новых каналов, получение сообщений, отправку операций и вызов и обработку ответов. Объекты диспетчера - это объекты получателя, однако реализации контракта обратного вызова в дуплексных службах также предоставляют свои объекты диспетчера для проверки, изменения или расширения.

Диспетчер каналов (и сопровождающий прослушиватель IChannelListener) удаляет сообщения из базового канала и передает их соответствующим диспетчерам конечной точки. Каждый диспетчер конечной точки имеет среду выполнения DispatchRuntime, направляющую сообщения в соответствующую операцию DispatchOperation, которая отвечает за вызов метода, реализующего операцию. Одновременно с этим вызываются различные необязательные и обязательные классы расширений. В этом разделе объясняется, как взаимодействуют все эти элементы и как можно изменять их свойства и подключать собственный код для расширения их базовой функциональности.

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

На следующем изображении представлено общее описание элементов архитектуры в службе.

The dispatch runtime architecture

Диспетчеры каналов

Объект ChannelDispatcher создается для связи прослушивателя IChannelListener по определенному URI (называемому "URI прослушивания") с экземпляром службы. Следовательно, каждый объект ServiceHost может иметь множество объектов ChannelDispatcher, каждый из которых связан только с одним прослушивателем и URI прослушивания. При поступлении сообщения диспетчер каналов ChannelDispatcher запрашивает все связанные объекты EndpointDispatcher, может ли данная конечная точка принять это сообщение, и передает его соответствующей конечной точке.

Все свойства, которые управляют временем существования и поведением сеанса канала, доступны для проверки или изменения в объекте ChannelDispatcher. Сюда относятся пользовательские инициализаторы канала, прослушиватель канала, узел, связанный контекст InstanceContext и т. д.

Диспетчеры конечных точек

Объект EndpointDispatcher отвечает за обработку сообщений от ChannelDispatcher, если адрес назначения сообщения соответствует свойству AddressFilter и действие сообщения соответствует свойству ContractFilter. Если принять сообщение могут два объекта EndpointDispatcher, то значение свойства FilterPriority определяет конечную точку с более высоким приоритетом.

Используйте диспетчер конечных точек EndpointDispatcher, чтобы получить две основные точки расширения модели службы (классы DispatchRuntime и DispatchOperation), которые можно использовать для настройки обработки диспетчера. Класс DispatchRuntime позволяет пользователям перехватывать и расширять диспетчер в области контракта (т. е. для всех сообщений контракта). Класс DispatchOperation позволяет пользователям перехватывать и расширять диспетчер в области операции (т. е. для всех сообщений операции).

Сценарии

Существует несколько причин для расширения диспетчера.

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

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

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

  • Пользовательская модель данных Пользователи могут иметь модель сериализации данных, отличной от поддерживаемых по умолчанию в WCF (а именно, System.Runtime.Serialization.DataContractSerializerи System.Xml.Serialization.XmlSerializerнеобработанных сообщениях). Для этого также можно реализовать интерфейсы модулей форматирования сообщений. Пример см. в разделе "Формататор операций" и "Селектор операций".

  • Пользовательская проверка параметров Пользователи могут проводить принудительную проверку допустимости типизированных параметров (в отличие от XML). Для этого также можно использовать интерфейсы инспекторов параметров.

  • Пользовательская диспетчеризация операций Пользователи могут диспетчеризовать не только действия, но и, например, элементы тела сообщения или пользовательские свойства сообщения. Это можно сделать с помощью интерфейса IDispatchOperationSelector. Пример см. в разделе "Формататор операций" и "Селектор операций".

  • Использование пулов объектов Пользователи могут объединять экземпляры в пул, вместо того чтобы выделять новый экземпляр для каждого вызова. Это можно реализовать с помощью интерфейсов поставщика экземпляров. Пример см. в разделе "Пулирование".

  • Аренда экземпляров Пользователи могут реализовать шаблон аренды для времени существования экземпляра, аналогичный шаблону удаленного взаимодействия .NET Framework. Это можно сделать с помощью интерфейсов времени существования контекста экземпляра.

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

  • Пользовательские поведения авторизации Пользователи могут осуществлять пользовательское управление доступом, расширяя элементы среды выполнения контракта или операции и добавляя проверки безопасности на основе маркеров, присутствующих в сообщении. Это можно сделать с помощью интерфейсов перехватчиков сообщений или перехватчиков параметров. Примеры см. в разделе "Расширяемость безопасности".

    Внимание

    Так как изменение свойств безопасности может скомпрометировать безопасность приложений WCF, настоятельно рекомендуется выполнять изменения, связанные с безопасностью, с осторожностью и тестированием перед развертыванием.

  • Пользовательские проверяющие элементы управления средой выполнения WCF Можно установить настраиваемые проверяющие средства, которые проверяют службы, контракты и привязки для применения политик корпоративного уровня в отношении приложений WCF. (Например, см. статью Практическое руководство. Блокировка конечных точек в Enterprise.)

Использование класса DispatchRuntime

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

  • Преобразование входящих сообщений в объекты и выпуск этих объектов в качестве вызовов методов на объекте службы.

  • Преобразование объектов, принятых от ответа на вызов операции службы, в исходящие сообщения.

Объект DispatchRuntime разрешает перехватывать и расширять диспетчеры каналов или конечных точек для всех сообщений в конкретном контракте, даже если сообщение не распознается. При приеме сообщения, не соответствующего ни одному из заданных в контракте сообщений, оно отправляется операции, возвращаемой свойством UnhandledDispatchOperation. Сведения о перехвате или расширении всех сообщений для конкретной операции см. в описании класса DispatchOperation.

Класс DispatchRuntime предоставляет четыре основных области расширяемости диспетчера.

  1. Компоненты канала используют свойства объекта DispatchRuntime и сопоставленного диспетчера каналов, возвращаемого свойством ChannelDispatcher, для настройки приема и закрытия каналов диспетчером каналов. Эта категория содержит свойства ChannelInitializers и InputSessionShutdownHandlers.

  2. Компоненты сообщения настраиваются для каждого обрабатываемого сообщения. Эта категория содержит свойства MessageInspectors, OperationSelector, Operations и ErrorHandlers.

  3. Компоненты экземпляра настраивают создание, время жизни и удаление экземпляров типа службы. За дополнительными сведениями о времени жизни объектов служб обратитесь к свойству InstanceContextMode. Эта категория содержит свойства InstanceContextInitializers и InstanceProvider.

  4. Компоненты, относящиеся к безопасности, могут использовать следующие свойства:

    • Свойство SecurityAuditLogLocation обозначает место записи событий аудита.

    • Свойство ImpersonateCallerForAllOperations определяет, будет ли служба пытаться производить олицетворение при помощи учетных данных, предоставленных во входящем сообщении.

    • Свойство MessageAuthenticationAuditLevel определяет, будут ли события успешной проверки подлинности сообщения записываться в журнал событий, указанный в SecurityAuditLogLocation.

    • Свойство PrincipalPermissionMode управляет способом задания свойства CurrentPrincipal.

    • Свойство ServiceAuthorizationAuditLevel указывает каким образом производится аудит событий авторизации.

    • Свойство SuppressAuditFailure указывает, будут ли подавляться некритические исключения, создаваемые в процессе ведения журнала.

Обычно объекты пользовательских расширений присваиваются свойству DispatchRuntime или вставляются в коллекцию поведением службы (объект, реализующий IServiceBehavior), поведением контракта (объект, реализующий IContractBehavior) или поведением конечной точки (объект, реализующий IEndpointBehavior). После этого объект устанавливающего поведения добавляется в соответствующую коллекцию поведений программно или реализацией пользовательского объекта BehaviorExtensionElement, чтобы разрешить вставку поведения с помощью файла конфигурации приложения.

Дуплексные клиенты (клиенты, реализующие контракт обратного вызова, заданный дуплексной службой) также имеют объект DispatchRuntime, доступ к которому можно получить с помощью свойства CallbackDispatchRuntime.

Использование класса DispatchOperation

Класс DispatchOperation - это местоположение изменений в среде выполнения и точка вставки для пользовательских расширений, область действия которых ограничивается только одной операцией службы. (Чтобы изменить поведение среды выполнения службы для всех сообщений в контракте, используйте класс DispatchRuntime.)

Установите изменения DispatchOperation с помощью пользовательского объекта поведения службы.

Используйте свойство Operations, чтобы найти объект DispatchOperation, который представляет определенную операцию службы.

Следующие свойства управляют выполнением среды выполнения на уровне операции.

  • Свойства Action, ReplyAction, FaultContractInfos, IsOneWay, IsTerminating и Name получают значения, соответствующие операции.

  • Свойства TransactionAutoComplete и TransactionRequired задают поведение транзакции.

  • Свойства ReleaseInstanceBeforeCall и ReleaseInstanceAfterCall управляют временем существования пользовательского объекта службы относительно InstanceContext.

  • Свойства DeserializeRequest, SerializeReply и Formatter разрешают явное управление преобразованием сообщений в объекты и наоборот.

  • Свойство Impersonation задает уровень олицетворения операции.

  • Свойство CallContextInitializers вставляет пользовательские расширения контекста вызова для операции.

  • Свойство AutoDisposeParameters управляет временем уничтожения объектов параметров.

  • Свойство Invoker вставляет пользовательский объект средства вызова.

  • Свойство ParameterInspectors позволяет вставлять пользовательский инспектор параметров, который можно использовать для проверки или изменения параметров и возвращаемых значений.

См. также