Extension des répartiteurs
Les répartiteurs sont chargés d'extraire des messages entrants des canaux sous-jacents, de les traduire dans des appels de méthode dans le code d'application et de renvoyer les résultats à l'appelant. Les extensions de répartiteurs vous permettent de modifier ce traitement. Vous pouvez implémenter des inspecteurs de messages ou de paramètres qui inspectent ou modifient le contenu des messages ou des paramètres. Vous pouvez modifier la manière dont les messages sont acheminés vers les opérations ou fournir d'autres fonctionnalités.
Cette rubrique décrit comment utiliser les classes DispatchRuntime et DispatchOperation dans une application cliente Windows Communication Foundation (WCF) afin de modifier le comportement d’exécution par défaut d’un répartiteur ou d’intercepter ou de modifier des messages, des paramètres ou des valeurs de retour avant ou à la suite de leur envoi ou de leur récupération dans la couche du canal. Pour plus d’informations sur le traitement du message d’exécution client équivalent, consultez Extension des clients. Pour comprendre le rôle joué par les types IExtensibleObject<T> pour accéder à l’état partagé entre différents objets de personnalisation de l’exécution, consultez Objets extensibles.
Répartiteurs
La couche de modèle de service effectue la conversion entre le modèle de programmation du développeur et l'échange de message sous-jacent, ou communément, couche de canal. Dans WCF, les répartiteurs de canal et de point de terminaison (ChannelDispatcher et EndpointDispatcher, respectivement) sont les composants de service chargés d’accepter de nouveaux canaux, de recevoir des messages, de distribuer et d’appeler l’opération et de traiter la réponse. Les objets de répartiteur sont des objets de récepteur, mais les implémentations de contrat de rappel dans les services duplex exposent également leurs objets de répartiteur pour l’inspection, le changement ou l’extension.
Le répartiteur de canal (et le IChannelListenerd'accompagnement) extrait des messages hors du canal sous-jacent et passe les messages à leurs répartiteurs de point de terminaison respectifs. Chaque répartiteur de point de terminaison a un DispatchRuntime qui route des messages au DispatchOperation approprié, chargé d'appeler la méthode qui implémente l'opération. Différentes classes d'extension facultatives et requises sont appelées. Cette rubrique explique comment ces morceaux s'ajustent les uns aux autres et comment vous pouvez modifier des propriétés et brancher votre propre code pour étendre les fonctionnalités de base.
Les propriétés de répartiteur et les objets de personnalisation modifiés sont insérés en utilisant un service, un point de terminaison, un contrat ou les objets de comportement de l'opération. Cette rubrique ne décrit pas comment utiliser des comportements. Pour plus d’informations sur les types utilisés pour insérer des modifications de répartiteur, consultez Configuration et extension de l’exécution à l’aide de comportements.
Le graphique suivant fournit une vue d'ensemble des éléments architecturaux dans un service.
Répartiteurs de canal
Un objet ChannelDispatcher est créé pour associer un objet IChannelListener à un URI donné (appelé « URI d'écoute ») avec une instance d'un service. Chaque objet ServiceHost peut avoir de nombreux objets ChannelDispatcher, chacun étant associé à un seul écouteur et à un seul URI d'écoute. Lorsqu'un message arrive, le ChannelDispatcher interroge chacun des objets EndpointDispatcher associés pour déterminer si le point de terminaison peut accepter le message, et passe le message à celui-ci.
Toutes les propriétés qui contrôlent la durée de vie et le comportement d'une session de canal sont disponibles pour l'inspection ou la modification sur l'objet ChannelDispatcher. Cela inclut les initialiseurs de canal personnalisés, l'écouteur de canal, l'hôte, le InstanceContextassocié, et ainsi de suite.
Répartiteurs de point de terminaison
L'objet EndpointDispatcher est chargé du traitement des messages à partir d'un ChannelDispatcher lorsque l'adresse de destination d'un message correspond à la propriété AddressFilter et que l'action de message correspond à la propriété ContractFilter. Si deux objets EndpointDispatcher peuvent accepter un message, la valeur de la propriété FilterPriority détermine le point de terminaison dont la priorité est la plus élevée.
Utilisez EndpointDispatcher pour acquérir les deux principaux points d’extension de modèle de service, les classes DispatchRuntime et DispatchOperation, que vous pouvez utiliser pour personnaliser le traitement du répartiteur. La classe DispatchRuntime permet aux utilisateurs d'intercepter et d'étendre le répartiteur à l'étendue du contrat (autrement dit, pour tous les messages dans un contrat). La classe DispatchOperation permet aux utilisateurs d'intercepter et d'étendre le répartiteur à une étendue d'opération (autrement dit, pour tous les messages dans une opération).
Scénarios
Plusieurs raisons d'étendre le répartiteur existent :
Validation personnalisée des messages. Les utilisateurs peuvent s'assurer qu'un message est valide pour un schéma spécifique. Cela peut être accompli en implémentant les interfaces d'intercepteur de messages. Pour obtenir un exemple, consultez Inspecteurs de message.
Enregistrement personnalisé des messages. Les utilisateurs peuvent inspecter et enregistrer des jeux de messages d'application qui transitent par un point de terminaison. Cela peut également être accompli à l'aide des interfaces de l'intercepteur de messages.
Transformations personnalisées des messages. Les utilisateurs peuvent appliquer certaines transformations au message dans l'exécution (par exemple, pour le contrôle de la version). Cela peut, à nouveau, être accompli à l'aide des interfaces de l'intercepteur de messages.
Modèle personnalisé de données. Les utilisateurs peuvent disposer d’un modèle de sérialisation des données autre que celui pris en charge par défaut dans WCF (à savoir System.Runtime.Serialization.DataContractSerializer, System.Xml.Serialization.XmlSerializer et messages bruts). Cela peut être accompli en implémentant les interfaces du module de formatage de messages. Pour obtenir un exemple, consultez Formateur d’opération et sélecteur d’opération.
Validation personnalisée des paramètres. Les utilisateurs peuvent s’assurer que les paramètres typés sont valides (contrairement à XML). Cela peut être accompli à l'aide des interfaces de l'inspecteur de paramètres.
Distribution personnalisée d'opérations. Les utilisateurs peuvent implémenter la distribution sur autre chose qu'une action. par exemple, sur le corps ou sur une propriété de message personnalisée. Cela peut s'effectuer à l'aide de l'interface IDispatchOperationSelector. Pour obtenir un exemple, consultez Formateur d’opération et sélecteur d’opération.
mise en pool d’objet Les utilisateurs peuvent regrouper des instances plutôt qu'allouer une nouvelle instance pour chaque appel. Cela peut être implémenté à l'aide des interfaces du fournisseur d'instances. Pour obtenir un exemple, consultez Regroupement.
Bail d'instances. Les utilisateurs peuvent implémenter un modèle de bail pour la durée de vie de l'instance, semblable à celui de .NET Framework Remoting. Cela peut s'effectuer à l'aide des interfaces de durée de vie de contexte d'instance.
Gestion personnalisée des erreurs. Les utilisateurs peuvent contrôler à la fois, comment les erreurs locales sont traitées et comment les erreurs sont retournées aux clients. Cela peut être implémenté à l'aide des interfaces IErrorHandler.
Comportements d'autorisation personnalisés. Les utilisateurs peuvent implémenter un contrôle d'accès personnalisé en étendant les morceaux d'exécution Contrat ou Opération et en ajoutant des vérifications de sécurité en fonction des jetons présents dans le message. Cela peut être accompli en utilisant soit les interfaces de l'intercepteur de messages, soit les interfaces de l'intercepteur de paramètres. Pour obtenir des exemples, consultez Extensibilité de la sécurité.
Attention
Parce qu’altérer des propriétés de sécurité peut compromettre la sécurité des applications WCF, il est fortement recommandé d’accorder un soin particulier aux changements relatifs à la sécurité et de procéder à des tests complets avant le déploiement.
Validateurs d'exécution WCF personnalisés. Vous pouvez installer des validateurs personnalisés qui examinent des services, des contrats et des liaisons pour mettre en vigueur des stratégies au niveau de l’entreprise en ce qui concerne les applications WCF. (Par exemple, voir Guide pratique pour verrouiller des points de terminaison dans l’entreprise.)
Utilisation de la classe DispatchRuntime
Utilisez la classe DispatchRuntime pour modifier le comportement par défaut d'un service ou d'un point de terminaison individuel, ou insérer des objets qui implémentent des changements personnalisés vers un ou deux des processus de service (ou processus client, dans le cas d'un client duplex) suivants :
La transformation de messages entrants dans les objets et la diffusion de ces objets comme appels de méthode sur un objet de service.
La transformation d'objets reçu de la réponse à un appel d'opération de service dans des messages sortants.
DispatchRuntime vous permet d'intercepter et d'étendre le canal ou le répartiteur de point de terminaison pour tous les messages à travers un contrat particulier, même lorsqu'un message n'est pas reconnu. Lorsqu'un message arrive et qu'il ne correspond à aucun message déclaré dans le contrat, il est distribué à l'opération retournée par la propriété UnhandledDispatchOperation. Pour intercepter ou étendre à travers tous les messages une opération particulière, consultez la classe DispatchOperation.
Il existe quatre domaines principaux d'extensibilité de répartiteur exposés par la classe DispatchRuntime :
Les composants de canal utilisent les propriétés de DispatchRuntime et celles du répartiteur de canal associé retournées par la propriété ChannelDispatcher pour personnaliser la façon dont le répartiteur de canal accepte et ferme des canaux. Cette catégorie inclut les propriétés ChannelInitializers et InputSessionShutdownHandlers.
Les composants de message sont personnalisés pour chaque message traité. Cette catégorie inclut les propriétés MessageInspectors, OperationSelector, Operations et ErrorHandlers.
Les composants d'instance personnalisent la création, la durée de vie et la suppression des instances du type de service. Pour plus d'informations sur la durée de vie de l'objet de service, consultez la propriété InstanceContextMode. Cette catégorie inclut les propriétés InstanceContextInitializers et InstanceProvider.
Les composants relatifs à la sécurité peuvent utiliser les propriétés suivantes :
SecurityAuditLogLocation indique où les événements d'audit sont écrits.
ImpersonateCallerForAllOperations contrôle si le service essaie d'emprunter l'identité à l'aide des informations d'identification fournies par le message entrant.
MessageAuthenticationAuditLevel contrôle si les événements d'authentification de message réussis sont écrits dans le journal des événements spécifié par SecurityAuditLogLocation.
PrincipalPermissionMode contrôle la façon dont la propriété CurrentPrincipal est définie.
ServiceAuthorizationAuditLevel spécifie comment l'audit d'événements d'autorisation est effectué.
SuppressAuditFailure spécifie s'il faut supprimer les exceptions non critiques qui se produisent pendant le processus d'enregistrement.
Généralement, des objets d'extension personnalisés sont affectés à une propriété DispatchRuntime ou insérés dans une collection par un comportement de service (un objet qui implémente IServiceBehavior), un comportement de contrat (un objet qui implémente IContractBehavior) ou un comportement de point de terminaison (un objet qui implémente IEndpointBehavior). Puis, l’objet de comportement installé est ajouté à la collection appropriée de comportements soit via le programme soit en implémentant un objet BehaviorExtensionElement personnalisé pour que le comportement soit inséré à l’aide d’un fichier de configuration d’application.
Les clients duplex (clients qui implémentent un contrat de rappel spécifié par un service duplex) ont également un objet DispatchRuntime qui peut être accédé à l'aide de la propriété CallbackDispatchRuntime.
Utilisation de la classe DispatchOperation
La classe DispatchOperation est l’emplacement des modifications d’exécution et le point d’insertion des extensions personnalisées qui sont limitées à une seule opération de service. (Pour modifier le comportement d'exécution du service pour tous les messages d'un contrat, utilisez la classe DispatchRuntime.)
Installez des changements DispatchOperation à l'aide d'un objet de comportement de service personnalisé.
Utilisez la propriété Operations pour localiser l'objet DispatchOperation qui représente une opération de service particulière.
La propriétés suivantes contrôlent l'exécution au niveau de l'opération :
Les propriétés Action, ReplyAction, FaultContractInfos, IsOneWay, IsTerminating et Name obtiennent les valeurs respectives pour l'opération.
TransactionAutoComplete et TransactionRequired spécifient le comportement de la transaction.
Les propriétés ReleaseInstanceBeforeCall et ReleaseInstanceAfterCall contrôlent la durée de vie de l'objet de service défini par l'utilisateur relatif à InstanceContext.
Les propriétés DeserializeRequest, SerializeReplyet Formatter activent le contrôle explicite sur la conversion des messages en objets et vice versa.
La propriété Impersonation spécifie le niveau d'emprunt d'identité de l'opération.
La propriété CallContextInitializers insère des extensions de contexte d’appel personnalisées pour l’opération.
La propriété AutoDisposeParameters contrôle à quel moment les objets de paramètre sont détruits.
La propriété Invoker insère un objet de méthode d'appel personnalisé.
La propriété ParameterInspectors vous permet d'insérer un inspecteur de paramètre personnalisé que vous pouvez utiliser pour inspecter ou modifier des paramètres et des valeurs de retour.