Partilhar via


Suporte a Configuração e Metadados

Este tópico descreve como habilitar a configuração e o suporte a metadados para associações e elementos de ligação.

Visão geral da configuração e metadados

Este tópico discute as tarefas a seguir, que são os itens opcionais 1, 2 e 4 na lista de tarefas Canais em desenvolvimento.

  • Habilitando o suporte ao arquivo de configuração para um elemento de vinculação.

  • Habilitando o suporte ao arquivo de configuração para uma ligação.

  • Exportando WSDL e asserções de política para um elemento vinculante.

  • Identificação de WSDL e asserções de política para inserir e configurar seu elemento de vinculação ou vinculação.

Para obter informações sobre como criar associações definidas pelo usuário e elementos de vinculação, consulte Criando ligações definidas pelo usuário e Criando um BindingElement, respectivamente.

Adicionando suporte à configuração

Para habilitar o suporte a arquivos de configuração para um canal, você deve implementar duas seções de configuração, System.ServiceModel.Configuration.BindingElementExtensionElement, que habilita o suporte à configuração para elementos de vinculação e o e System.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>, que habilita o System.ServiceModel.Configuration.StandardBindingElement suporte à configuração para associações.

Uma maneira mais fácil de fazer isso é usar a ferramenta de exemplo ConfigurationCodeGenerator para gerar código de configuração para suas ligações e elementos de ligação.

Estendendo BindingElementExtensionElement

O código de exemplo a seguir é retirado do exemplo Transport: UDP . O UdpTransportElement é um BindingElementExtensionElement que expõe UdpTransportBindingElement ao sistema de configuração. Com algumas substituições básicas, o exemplo define o nome da seção de configuração, o tipo do elemento de vinculação e como criar o elemento de ligação. Os usuários podem então registrar a seção de extensão em um arquivo de configuração da seguinte maneira.

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

A extensão pode ser referenciada a partir de ligações personalizadas para usar UDP como transporte.

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

Adicionando configuração para uma associação

A seção SampleProfileUdpBindingCollectionElement é uma StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration> que expõe SampleProfileUdpBinding ao sistema de configuração. A maior parte da implementação é delegada ao , que deriva SampleProfileUdpBindingConfigurationElementde StandardBindingElement. O SampleProfileUdpBindingConfigurationElement tem propriedades que correspondem às propriedades em SampleProfileUdpBindinge funções a serem mapeadas a ConfigurationElement partir da associação. Finalmente, o OnApplyConfiguration método é substituído no SampleProfileUdpBinding, conforme mostrado no código de exemplo a seguir.

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;  
}  

Para registrar esse manipulador no sistema de configuração, adicione a seção a seguir ao arquivo de configuração relevante.

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

Em seguida, ele pode ser referenciado na seção de configuração 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>  

Adicionando suporte a metadados para um elemento de vinculação

Para integrar um canal no sistema de metadados, ele deve suportar tanto a importação quanto a exportação de políticas. Isso permite que ferramentas como ServiceModel Metadata Utility Tool (Svcutil.exe) gerem clientes do elemento de ligação.

Adicionando suporte a WSDL

O elemento de ligação de transporte em uma associação é responsável por exportar e importar informações de endereçamento em metadados. Ao usar uma associação SOAP, o elemento de ligação de transporte também deve exportar um URI de transporte correto nos metadados. O código de exemplo a seguir é retirado do exemplo Transport: UDP .

Exportação WSDL

Para exportar informações de endereçamento, o UdpTransportBindingElement implementa a System.ServiceModel.Description.IWsdlExportExtension interface. O IWsdlExportExtension.ExportEndpoint método adiciona as informações de endereçamento corretas à porta WSDL.

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

A UdpTransportBindingElement implementação do método também exporta ExportEndpoint um URI de transporte quando o ponto de extremidade usa uma ligação SOAP:

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

Importação WSDL

Para estender o sistema de importação WSDL para lidar com a importação dos endereços, adicione a seguinte configuração ao arquivo de configuração para Svcutil.exe conforme mostrado no arquivo Svcutil.exe.config:

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

Ao executar Svcutil.exe, há duas opções para obter Svcutil.exe para carregar as extensões de importação WSDL:

  1. Aponte Svcutil.exe para o arquivo de configuração usando o arquivo /SvcutilConfig:<file>.

  2. Adicione a seção de configuração ao Svcutil.exe.config no mesmo diretório que Svcutil.exe.

O UdpBindingElementImporter tipo implementa a System.ServiceModel.Description.IWsdlImportExtension interface. O ImportEndpoint método importa o endereço da porta WSDL:

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

Adicionando suporte a políticas

O elemento de vinculação personalizado pode exportar asserções de política na associação WSDL para um ponto de extremidade de serviço para expressar os recursos desse elemento de vinculação. O código de exemplo a seguir é retirado do exemplo Transport: UDP .

Exportação de políticas

O UdpTransportBindingElement tipo implementa System.ServiceModel.Description.IPolicyExportExtension para adicionar suporte para exportar política. Como resultado, System.ServiceModel.Description.MetadataExporter inclui UdpTransportBindingElement na geração de política para qualquer vinculação que a inclua.

No IPolicyExportExtension.ExportPolicy, adicione uma asserção para UDP e outra asserção se o canal estiver no modo de multicast. Isso ocorre porque o modo de multicast afeta como a pilha de comunicação é construída e, portanto, deve ser coordenada entre ambos os lados.

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));  
}  

Como os elementos de vinculação de transporte personalizados são responsáveis por lidar com o endereçamento, a System.ServiceModel.Description.IPolicyExportExtension implementação no deve também lidar com a UdpTransportBindingElement exportação das asserções de política WS-Addressing apropriadas para indicar a versão do WS-Addressing que está sendo usada.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);  

Importação de políticas

Para estender o sistema de importação de política, adicione a seguinte configuração ao arquivo de configuração para Svcutil.exe conforme mostrado no arquivo Svcutil.exe.config:

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

Em seguida, implementamos System.ServiceModel.Description.IPolicyImportExtension a partir de nossa classe registrada (UdpBindingElementImporter). Em IPolicyImportExtension.ImportPolicy, examine as asserções no namespace apropriado e processe as para gerar o transporte e verificar se ele é multicast. Além disso, remova as asserções que o importador manipula da lista de asserções vinculativas. Novamente, ao executar Svcutil.exe, há duas opções de integração:

  1. Aponte Svcutil.exe para o nosso arquivo de configuração usando o /SvcutilConfig:<file>.

  2. Adicione a seção de configuração ao Svcutil.exe.config no mesmo diretório que Svcutil.exe.

Adicionando um importador de vinculação padrão personalizado

Svcutil.exe e o System.ServiceModel.Description.WsdlImporter tipo, por padrão, reconhecem e importam ligações fornecidas pelo sistema. Caso contrário, a associação será importada como uma System.ServiceModel.Channels.CustomBinding instância. Para permitir Svcutil.exe e importar WsdlImporter o SampleProfileUdpBindingUdpBindingElementImporter também atua como um importador de vinculação padrão personalizado.

Um importador de vinculação padrão personalizado implementa o ImportEndpoint método na System.ServiceModel.Description.IWsdlImportExtension interface para examinar a System.ServiceModel.Channels.CustomBinding instância importada de metadados para ver se ela poderia ter sido gerada por vinculação padrão específica.

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;  
        }  
    }  
}  

Geralmente, a implementação de um importador de vinculação padrão personalizado envolve a verificação das propriedades dos elementos de vinculação importados para verificar se apenas as propriedades que poderiam ter sido definidas pela associação padrão foram alteradas e todas as outras propriedades são seus padrões. Uma estratégia básica para implementar um importador de vinculação padrão é criar uma instância da associação padrão, propagar as propriedades dos elementos de vinculação para a instância de vinculação padrão que a vinculação padrão suporta e comparar os elementos de ligação da associação padrão com os elementos de vinculação importados.