Configuration et extension de l'exécution à l'aide de comportements

Les comportements vous permettent de modifier le comportement par défaut et d’ajouter des extensions personnalisées qui inspectent et valident la configuration de service ou modifient le comportement au moment de l’exécution dans les applications clientes et de service Windows Communication Foundation (WCF). Cette rubrique décrit les interfaces de comportement, la méthode utilisée pour les implémenter, et comment les ajouter par programme à la description de service (dans une application de service), au point de terminaison (dans une application cliente) ou dans un fichier de configuration. Pour plus d’informations sur l’utilisation de comportements fournis par le système, consultez Spécification du comportement du service au moment de l’exécution et Spécification du comportement du client au moment de l’exécution.

Comportements

Les types de comportements sont aux objets de description de service ou de point de terminaison de service (sur le service ou le client, respectivement) avant que ces objets ne soient utilisés par Windows Communication Foundation (WCF) pour créer une exécution qui exécute un service WCF ou un client WCF. Lorsque ces comportements sont appelés pendant le processus de construction d’exécution, ils sont ensuite capables d’accéder aux méthodes et propriétés d’exécution qui modifient l’exécution construite par le contrat, les liaisons et les adresses.

Méthodes de comportement

Tous les comportements ont une méthode AddBindingParameters, une méthode ApplyDispatchBehavior, une méthode Validate et une méthode ApplyClientBehavior avec une exception : IServiceBehavior ne pouvant pas s'exécuter dans un client, il n'implémente pas ApplyClientBehavior.

  • Utilisez la méthode AddBindingParameters pour modifier ou ajouter des objets personnalisés à une collection à laquelle les liaisons personnalisées peuvent accéder lorsque l'exécution est construite. Par exemple, la méthode utilisée pour spécifier les exigences de protection affecte la façon dont le canal est construit, mais n’est pas connue par le développeur de canal.

  • Utilisez la méthode Validate pour examiner l'arborescence de description et l'objet d'exécution correspondant afin de s'assurer qu'elle est conforme à certains critères.

  • Utilisez les méthodes ApplyDispatchBehavior et ApplyClientBehavior pour examiner l’arborescence de description et modifier l’exécution pour une portée spécifique sur le service ou le client. Vous pouvez également insérer des objets d’extension.

    Notes

    Bien qu'une arborescence de description soit fournie dans ces méthodes, elle l'est uniquement à des fins d'examen. Si une arborescence de description est modifiée, le comportement n’est pas défini.

Les propriétés que vous pouvez modifier et les interfaces de personnalisation que vous pouvez implémenter sont accessibles via les classes d'exécution de service et de client. Les types de services sont les classes DispatchRuntime et DispatchOperation. Les types de client sont les classes ClientRuntime et ClientOperation. Les classes ClientRuntime et DispatchRuntime sont les points d'entrée d'extensibilité pour accéder aux propriétés d'exécution à l'échelle du service et du client et aux collections d'extensions, respectivement. De la même façon, les classes ClientOperation et DispatchOperation exposent les propriétés d’exécution d’opération de service et d’opération de client et les collections d’extensions, respectivement. Toutefois, vous pouvez accéder à l'objet d'exécution de portée plus large à partir de l'objet d'exécution d'opération et vice versa, si nécessaire.

Notes

Pour obtenir des informations complémentaires sur les propriétés d’exécution et les types d’extensions que vous pouvez utiliser pour modifier le comportement d’exécution d’un client, consultez Extension de clients. Pour en savoir plus sur les propriétés d’exécution et les types d’extensions que vous pouvez utiliser pour modifier le comportement d’exécution d’un répartiteur de service, consultez Extension des répartiteurs.

La plupart des utilisateurs WCF n’interagissent pas directement avec l’exécution ; au lieu de cela, ils utilisent des constructions de modèle de programmation principales comme des points de terminaison, des contrats, des liaisons, des adresses et des attributs de comportement sur les classes ou les comportements des fichiers de configuration. Ces constructions formes l’arborescence de description, qui est la spécification complète permettant de construire une exécution afin de prendre en charge un service ou un client décrit par l’arborescence de description.

Il existe quatre types de comportements dans WCF :

Vous pouvez ajouter ces comportements aux divers objets de description en implémentant des attributs personnalisés, à l'aide de fichiers de configuration d'application, ou en les ajoutant directement à la collection de comportements sur l'objet de description approprié. Cependant, ils doivent être ajoutés à un objet de description de service ou de description de point de terminaison de service avant d'appeler ICommunicationObject.Open sur le ServiceHost ou un ChannelFactory<TChannel>.

Portées de comportement

Il existe quatre types de comportement, chacun d'entre eux correspondant à une portée spécifique d'accès d'exécution.

Comportements de service

Les comportements de service, qui implémentent IServiceBehavior, constituent le mécanisme principal vous permettant de modifier l'ensemble de l'exécution du service. Il existe trois mécanismes d'ajout de comportements de service à un service.

  1. En utilisant un attribut sur la classe de service. Lorsque ServiceHost est construit, l'implémentation ServiceHost utilise la réflexion pour découvrir l'ensemble d'attributs sur le type du service. Si ces attributs sont des implémentations de IServiceBehavior, ils sont ajoutés à la collection de comportements sur ServiceDescription. Cela permet à ces comportements de participer à la construction de l'exécution du service.

  2. En ajoutant par programme le comportement à la collection de comportements sur ServiceDescription. Pour ce faire, utilisez les lignes de code suivantes :

    ServiceHost host = new ServiceHost(/* Parameters */);  
    host.Description.Behaviors.Add(/* Service Behavior */);  
    
  3. En implémentant un BehaviorExtensionElement personnalisé qui étend la configuration. Cela active l'utilisation du comportement de service à partir des fichiers de configuration d'application.

Les exemples de comportements de service dans WCF incluent l’attribut ServiceBehaviorAttribute, ServiceThrottlingBehavior et le comportement ServiceMetadataBehavior.

Comportements de contrat

Les comportements de contrat, qui implémentent l'interface IContractBehavior, permettent d'étendre à la fois l'exécution du client et du service sur un contrat.

Il existe deux mécanismes d'ajout de comportement de contrat à un contrat. Le premier consiste à créer un attribut personnalisé à utiliser sur l'interface de contrat. Lorsqu’une interface de contrat est passée à un ServiceHost ou à un ChannelFactory<TChannel>, WCF examine les attributs sur l’interface. Si les attributs sont des implémentations de IContractBehavior, ils sont ajoutés à la collection de comportements sur le System.ServiceModel.Description.ContractDescription créé pour cette interface.

Vous pouvez également implémenter System.ServiceModel.Description.IContractBehaviorAttribute sur l'attribut de comportement de contrat personnalisé. Dans ce cas, le comportement se présente comme suit lorsqu'il est appliqué aux éléments suivants :

•Interface de contrat. Dans ce cas, le comportement est appliqué à tous les contrats de ce type dans tous les points de terminaison et WCF ignore la valeur de la propriété IContractBehaviorAttribute.TargetContract.

•Classe de service. Dans ce cas, le comportement n'est appliqué qu'aux points de terminaison dont le contrat est la valeur de la propriété TargetContract.

•Classe de rappel. Dans ce cas, le comportement est appliqué au point de terminaison du client duplex et WCF ignore la valeur de la propriété TargetContract.

Le deuxième mécanisme consiste à ajouter le comportement à la collection de comportements sur ContractDescription.

Les exemples de comportements de contrat dans WCF incluent l’attribut System.ServiceModel.DeliveryRequirementsAttribute. Pour plus d'informations et obtenir un exemple, consultez la rubrique de référence.

Comportements de point de terminaison

Les comportements de point de terminaison, qui implémentent IEndpointBehavior, constituent le mécanisme principal vous permettant de modifier l'ensemble de l'exécution du service ou du client pour un point de terminaison spécifique.

Il existe deux mécanismes d'ajout de comportements de point de terminaison à un service.

  1. Ajoutez le comportement à la propriété Behaviors.

  2. Implémentez un BehaviorExtensionElement personnalisé qui étend la configuration.

Pour plus d'informations et obtenir un exemple, consultez la rubrique de référence.

Comportements d'opération

Les comportements d'opération, qui implémentent l'interface IOperationBehavior, permettent d'étendre à la fois l'exécution du client et du service pour chaque opération.

Il existe deux mécanismes d'ajout de comportements d'opération à une opération. Le premier consiste à créer un attribut personnalisé à utiliser sur la méthode qui modélise l'opération. Lorsqu’une opération est ajoutée à un ServiceHost ou à un ChannelFactory, WCF ajoute tous les attributs IOperationBehavior à la collection de comportements sur le OperationDescription créé pour cette opération.

Le deuxième mécanisme consiste à ajouter directement le comportement à la collection de comportements sur un OperationDescription construit.

Les exemples de comportements d’opération dans WCF incluent OperationBehaviorAttribute et TransactionFlowAttribute.

Pour plus d'informations et obtenir un exemple, consultez la rubrique de référence.

Création de comportements à l'aide de la configuration

Les comportements de service, de point de terminaison et de contrat peuvent, de par leur conception, être spécifiés dans le code ou à l'aide d'attributs ; seuls les comportements de service et de point de terminaison peuvent être configurés à l'aide de fichiers d'application ou de configuration Web. L’exposition des comportements à l’aide d’attributs permet aux développeurs de spécifier un comportement au moment de la compilation qui ne peut pas être ajouté, supprimé ou modifié au moment de l’exécution. Cela s’avère souvent approprié pour les comportements qui sont systématiquement requis pour l’opération correcte d’un service (par exemple, les paramètres associés à la transaction de l’attribut System.ServiceModel.ServiceBehaviorAttribute). L'exposition des comportements à l'aide de la configuration permet aux développeurs de laisser la spécification et la configuration de ces comportements à ceux qui déploient le service. Cela s'avère approprié pour les comportements qui sont des composants facultatifs ou qui représentent une autre configuration spécifique au déploiement, dans le cas par exemple de l'exposition des métadonnées pour le service ou de la configuration d'autorisation spécifique d'un service.

Notes

Vous pouvez également utiliser des comportements qui prennent en charge la configuration afin d'appliquer les stratégies d'application de la société en les insérant dans le fichier de configuration machine.config et en verrouillant ces éléments. Pour obtenir une description et un exemple, consultez Guide pratique pour verrouiller des points de terminaison dans l’entreprise.

Pour exposer un comportement à l’aide de la configuration, un développeur doit créer une classe dérivée de BehaviorExtensionElement, puis enregistrer cette extension avec la configuration.

L’exemple de code suivant indique comment un IEndpointBehavior implémente BehaviorExtensionElement :

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

Pour que le système de configuration charge un BehaviorExtensionElement personnalisé, il doit être enregistré en tant qu’extension. L'exemple de code suivant présente le fichier de configuration du comportement de point de terminaison précédent :

<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 est le type d’extension de comportement et HostApplication est le nom de l’assembly dans lequel cette classe a été compilée.

Ordre d'évaluation

System.ServiceModel.ChannelFactory<TChannel> et System.ServiceModel.ServiceHost sont chargés de générer l'exécution à partir de la description et du modèle de programmation. Les comportements, comme décrit précédemment, contribuent à ce processus de génération au niveau du service, du point de terminaison, du contrat et de l'opération.

ServiceHost applique les comportements dans l'ordre suivant :

  1. Service

  2. Contrat

  3. Point de terminaison

  4. Opération

Dans une collection de comportements, aucun ordre n’est garanti.

ChannelFactory<TChannel> applique les comportements dans l'ordre suivant :

  1. Contrat

  2. Point de terminaison

  3. Opération

Dans une collection de comportements, à nouveau aucun ordre n’est garanti.

Ajout de comportements par programme

Les propriétés de System.ServiceModel.Description.ServiceDescription dans l'application de service ne doivent pas être modifiées à l'issue de la méthode CommunicationObject.OnOpening sur System.ServiceModel.ServiceHostBase. Certains membres, tels que la propriété ServiceHostBase.Credentials et les méthodes AddServiceEndpoint sur ServiceHostBase et System.ServiceModel.ServiceHost, lèvent une exception s'ils sont modifiés une fois ce stade passé. D'autres membres peuvent être modifiés, mais le résultat n'est pas défini.

De la même façon, sur le client les valeurs System.ServiceModel.Description.ServiceEndpoint ne doivent pas être modifiées après l'appel à OnOpening sur System.ServiceModel.ChannelFactory. La propriété ChannelFactory.Credentials lève une exception si elle est modifiée une fois ce stade passé, mais les autres valeurs de description du client peuvent être modifiées sans erreur. Toutefois, le résultat n'est pas défini.

Aussi bien pour le service que le client, il est recommandé de modifier la description avant d'appeler CommunicationObject.Open.

Règles d'héritage pour les attributs de comportement

L'ensemble des quatre types de comportements peuvent être remplis à l'aide d'attributs (comportements de service et comportements de contrat). Ces attributs étant définis sur des membres et objets managés, et les membres et objets managés prenant en charge l'héritage, il est nécessaire de définir la façon dont les attributs de comportement fonctionnent dans le contexte d'héritage.

À un niveau élevé, la règle veut que pour une portée spécifique (par exemple, service, contrat ou opération), tous les attributs de comportement de la hiérarchie d'héritage pour cette portée soient appliqués. S'il existe deux attributs de comportement du même type, seul le type le plus dérivé est utilisé.

Comportements de service

Pour une classe de service donnée, l'ensemble des attributs de comportement de service sur cette classe, et sur les parents de celle-ci, sont appliqués. Si le même type d'attribut est appliqué à plusieurs emplacements dans la hiérarchie d'héritage, le type le plus dérivé est utilisé.

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

Par exemple, dans le cas précédent, le service B se termine par InstanceContextMode de Single, un mode AspNetCompatibilityRequirementsMode de Allowed et ConcurrencyMode de Single. ConcurrencyMode a la valeur Single, car l'attribut ServiceBehaviorAttribute sur le service B est « plus dérivé » que celui sur le service A.

Comportements de contrat

Pour un contrat donné, tous les attributs de comportement de contrat sur cette interface et sur les parents de celle-ci, sont appliqués. Si le même type d'attribut est appliqué à plusieurs emplacements dans la hiérarchie d'héritage, le type le plus dérivé est utilisé.

Comportements d'opération

Si une opération donnée ne substitue pas une opération virtuelle ou abstraite existante, aucune règle d'héritage ne s'applique.

Si une opération substitue une opération existante, alors tous les attributs de comportement d'opération sur cette opération, et sur les parents de celle-ci, sont appliqués. Si le même type d'attribut est appliqué à plusieurs emplacements dans la hiérarchie d'héritage, le type le plus dérivé est utilisé.