Prise en charge de la configuration et des métadonnées

Cette rubrique décrit comment activer la prise en charge de la configuration et des métadonnées pour les liaisons et éléments de liaison.

Vue d'ensemble de la configuration et des métadonnées

Cette rubrique présente les tâches suivantes, qui correspondent aux éléments facultatifs 1, 2 et 4 de la liste des tâches Développement de canaux.

  • Activation de la prise en charge du fichier de configuration pour un élément de liaison.

  • Activation de la prise en charge du fichier de configuration pour une liaison.

  • Exportation des assertions WSDL et de stratégie pour un élément de liaison.

  • Identification des assertions WSDL et de stratégie afin d’insérer et de configurer votre liaison ou élément de liaison.

Pour plus d’informations sur la création de liaisons et d’éléments de liaison définis par l’utilisateur, consultez Création de liaisons définies par l’utilisateur et Création d’un élément de liaison, respectivement.

Ajout de la prise en charge de la configuration

Pour activer la prise en charge du fichier de configuration pour un canal, vous devez implémenter deux sections de configuration : System.ServiceModel.Configuration.BindingElementExtensionElement qui active la prise en charge de la configuration pour les éléments de liaison, et System.ServiceModel.Configuration.StandardBindingElement et System.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration> qui activent la prise en charge de la configuration pour les liaisons.

Utiliser l’exemple d’outil ConfigurationCodeGenerator pour générer le code de configuration de vos liaisons et éléments de liaison constitue un moyen plus simple d’y parvenir.

Extension de BindingElementExtensionElement

L’exemple de code suivant est extrait de l’exemple Transport : UDP. UdpTransportElement est un objet BindingElementExtensionElement qui expose UdpTransportBindingElement au système de configuration. Avec quelques substitutions de base, l’exemple définit le nom de section de configuration, le type de l’élément de liaison et la méthode utilisée pour le créer. Les utilisateurs peuvent ensuite enregistrer la section d’extension dans un fichier de configuration comme suit.

<configuration>  
  <system.serviceModel>  
    <extensions>  
      <bindingElementExtensions>  
      <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />  
      </bindingElementExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

L'extension peut être référencée à partir des liaisons personnalisées pour utiliser UDP comme transport.

<configuration>  
  <system.serviceModel>  
    <bindings>  
      <customBinding>  
       <binding configurationName="UdpCustomBinding">  
         <udpTransport/>  
       </binding>  
      </customBinding>  
    </bindings>  
  </system.serviceModel>  
</configuration>  

Ajout de la configuration pour une liaison

La section SampleProfileUdpBindingCollectionElement est un StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration> qui expose SampleProfileUdpBinding au système de configuration. Le bloc de l'implémentation est délégué à SampleProfileUdpBindingConfigurationElement, qui dérive de StandardBindingElement. SampleProfileUdpBindingConfigurationElement possède des propriétés qui correspondent à celles de SampleProfileUdpBinding, ainsi que des fonctions de mappage à partir de la liaison ConfigurationElement. Enfin, la méthode OnApplyConfiguration est substituée dans SampleProfileUdpBinding, tel qu'indiqué dans l'exemple de code suivant.

protected override void OnApplyConfiguration(string configurationName)  
{  
            if (binding == null)  
                throw new ArgumentNullException("binding");  
  
            if (binding.GetType() != typeof(SampleProfileUdpBinding))  
            {  
                var expectedType = typeof(SampleProfileUdpBinding).AssemblyQualifiedName;
                var typePassedIn = binding.GetType().AssemblyQualifiedName;
                throw new ArgumentException($"Invalid type for binding. Expected type: {expectedType}. Type passed in: {typePassedIn}.");  
            }  
            SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;  
  
            udpBinding.OrderedSession = this.OrderedSession;  
            udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;  
            udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;  
            if (this.ClientBaseAddress != null)  
                   udpBinding.ClientBaseAddress = ClientBaseAddress;  
}  

Pour enregistrer ce gestionnaire avec le système de configuration, ajoutez la section suivante au fichier de configuration approprié.

<configuration>  
  <configSections>  
     <sectionGroup name="system.serviceModel">  
         <sectionGroup name="bindings">  
                 <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />  
         </sectionGroup>  
     </sectionGroup>  
  </configSections>  
</configuration>  

Il pourra ensuite être référencé à partir de la section de configuration <system.serviceModel>.

<configuration>  
  <system.serviceModel>  
    <client>  
      <endpoint configurationName="calculator"  
                address="soap.udp://localhost:8001/"
                bindingConfiguration="CalculatorServer"  
                binding="sampleProfileUdpBinding"
                contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

Ajout de la prise en charge des métadonnées pour un élément de liaison

Pour intégrer un canal dans le système de métadonnées, il doit à la fois prendre en charge l'importation et l'exportation de stratégie. Cela permet aux outils tels que Service Model Metadata Utility Tool (Svcutil.exe) de générer des clients de l’élément de liaison.

Ajout de la prise en charge WSDL

L’élément de liaison de transport d’une liaison est chargé d’exporter et d’importer les informations d’adressage dans les métadonnées. Lors de l'utilisation d'une liaison SOAP, l'élément de liaison de transport doit également exporter un URI de transport correct dans les métadonnées. L’exemple de code suivant est extrait de l’exemple Transport : UDP.

Exportation WSDL

Pour exporter des informations d’adressage, UdpTransportBindingElement implémente l’interface System.ServiceModel.Description.IWsdlExportExtension. La méthode IWsdlExportExtension.ExportEndpoint ajoute les informations d'adressage correctes au port WSDL.

if (context.WsdlPort != null)  
{  
    AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);  
}  

L’implémentation UdpTransportBindingElement de la méthode ExportEndpoint exporte également un URI de transport lorsque le point de terminaison utilise une liaison SOAP :

WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);  
if (soapBinding != null)  
{  
    soapBinding.Transport = UdpPolicyStrings.UdpNamespace;  
}  

Importation WSDL

Pour étendre le système d'importation WSDL afin de gérer l'importation des adresses, ajoutez la configuration suivante au fichier de configuration de Svcutil.exe, tel qu'indiqué dans le fichier Svcutil.exe.config :

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <wsdlImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </wsdlImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

Lorsque vous exécutez Svcutil.exe, deux méthodes permettent de faire en sorte que Svcutil.exe charge les extensions d’importation WSDL :

  1. Pointez Svcutil.exe vers le fichier de configuration en utilisant /SvcutilConfig:<fichier>.

  2. Ajoutez la section de configuration à Svcutil.exe.config dans le répertoire où se trouve Svcutil.exe.

Le type UdpBindingElementImporter implémente l'interface System.ServiceModel.Description.IWsdlImportExtension. La méthode ImportEndpoint importe l'adresse à partir du port WSDL :

BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();  
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();  
if (transportBindingElement is UdpTransportBindingElement)  
{  
    ImportAddress(context);  
}  

Ajout de la prise en charge de la stratégie

L’élément de liaison personnalisé peut exporter des assertions de stratégie dans la liaison WSDL d’un point de terminaison de service pour exprimer les fonctionnalités de cet élément de liaison. L’exemple de code suivant est extrait de l’exemple Transport : UDP.

Exportation de stratégie

Le type UdpTransportBindingElement implémente System.ServiceModel.Description.IPolicyExportExtension pour ajouter la prise en charge de l’exportation de stratégie. En conséquence, System.ServiceModel.Description.MetadataExporter inclut UdpTransportBindingElement dans la génération de stratégie des liaisons qui l’incluent.

Dans IPolicyExportExtension.ExportPolicy, ajoutez une assertion pour UDP et une autre si le canal est en mode multicast. Cela est dû au fait que le mode multicast affecte la manière dont la pile est construite, et doit donc être coordonné entre les deux côtés.

ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();  
XmlDocument xmlDocument = new XmlDocument();  
bindingAssertions.Add(xmlDocument.CreateElement(  
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));  
if (Multicast)  
{  
    bindingAssertions.Add(xmlDocument.CreateElement(  
UdpPolicyStrings.Prefix, UdpPolicyStrings.MulticastAssertion,     UdpPolicyStrings.UdpNamespace));  
}  

Les éléments de liaison de transport personnalisés étant chargés de gérer l’adressage, l’implémentation System.ServiceModel.Description.IPolicyExportExtension sur UdpTransportBindingElement doit également gérer l’exportation des assertions de stratégie WS-Addressing appropriées pour indiquer la version de WS-Addressing utilisée.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);  

Importation de stratégie

Pour étendre le système d'importation de stratégie, ajoutez la configuration suivante au fichier de configuration de Svcutil.exe, tel qu'indiqué dans le fichier Svcutil.exe.config :

<configuration>  
  <system.serviceModel>  
    <client>  
      <metadata>  
        <policyImporters>  
          <extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />  
        </policyImporters>  
      </metadata>  
    </client>  
  </system.serviceModel>  
</configuration>  

Puis nous implémentons System.ServiceModel.Description.IPolicyImportExtension à partir de la classe enregistrée (UdpBindingElementImporter). Dans IPolicyImportExtension.ImportPolicy, examinez les assertions dans l'espace de noms approprié et traitez celles permettant de générer le transport et de vérifier s'il est multicast. En outre, supprimez les assertions gérées par l'importateur de la liste des assertions de liaison. Une fois encore, il existe deux méthodes d'intégration possibles lorsque vous exécutez Svcutil.exe :

  1. Pointez Svcutil.exe vers notre fichier de configuration à l’aide de /SvcutilConfig:<fichier>.

  2. Ajoutez la section de configuration à Svcutil.exe.config dans le répertoire où se trouve Svcutil.exe.

Ajout d'un importateur de liaison standard personnalisé

Par défaut, Svcutil.exe et le type System.ServiceModel.Description.WsdlImporter reconnaissent et importent les liaisons fournies par le système. Sinon, la liaison est importée en tant qu'instance System.ServiceModel.Channels.CustomBinding. Pour permettre à Svcutil.exe et WsdlImporter d’importer SampleProfileUdpBinding, UdpBindingElementImporter agit également comme un importateur de liaison standard personnalisé.

Un importateur de liaison standard personnalisé implémente la méthode ImportEndpoint sur l’interface System.ServiceModel.Description.IWsdlImportExtension pour examiner l’instance System.ServiceModel.Channels.CustomBinding importée à partir des métadonnées afin de vérifier si elle peut avoir été générée par une liaison standard spécifique.

if (context.Endpoint.Binding is CustomBinding)  
{  
    Binding binding;  
    if (transportBindingElement is UdpTransportBindingElement)  
    {  
        //if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the  
        //generated config file for better typed generation.  
        if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))  
        {  
            binding.Name = context.Endpoint.Binding.Name;  
            binding.Namespace = context.Endpoint.Binding.Namespace;  
            context.Endpoint.Binding = binding;  
        }  
    }  
}  

En général, l’implémentation d’un importateur de liaison standard personnalisé implique la vérification des propriétés des éléments de liaison importés afin de s’assurer que seules les propriétés pouvant avoir été définies par la liaison standard ont été modifiées et que toutes les autres ont été définies à leurs valeurs par défaut. L’une des stratégies de base permettant d’implémenter un importateur de liaison standard consiste à créer une instance de la liaison standard, à propager les propriétés des éléments de liaison vers l’instance de liaison standard que la liaison standard prend en charge, et à comparer les éléments de liaison de la liaison standard avec les éléments de liaison importés.