Compartilhar via


Suporte para configuração e metadados

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

Visão geral de configuração e metadados

Este tópico discute as seguintes tarefas, que são itens opcionais 1, 2 e 4 na lista de tarefas Desenvolvendo Canais .

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

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

  • Exportação do WSDL e das declarações de política para um elemento de associação.

  • Identificação do WSDL e das declarações de política para inserir e configurar a associação ou o elemento de associação.

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

Adicionando suporte à configuração

Para habilitar o suporte de arquivo de configuração para um canal, você deve implementar duas seções de configuração, System.ServiceModel.Configuration.BindingElementExtensionElement, que permitem o suporte de configuração para elementos de associação, e System.ServiceModel.Configuration.StandardBindingElement e System.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>, que permitem o suporte de 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 associações e elementos de associação.

Extensão do BindingElementExtensionElement

O código de exemplo a seguir é obtido do exemplo Transporte: UDP . 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 associação e como criar o elemento de associação. Os usuários podem 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 em associações personalizadas para usar o UDP como o transporte.

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

Adição de 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 SampleProfileUdpBindingConfigurationElement, que deriva de StandardBindingElement. O SampleProfileUdpBindingConfigurationElement tem propriedades que correspondem às propriedades em SampleProfileUdpBinding e funções a serem mapeadas a partir da associação ConfigurationElement. Por fim, 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 ao sistema de metadados, ele deve dar suporte à importação e à exportação da política. Isso permite que ferramentas como a ServiceModel Metadata Utility Tool (Svcutil.exe) gerem clientes do elemento de associação.

Adicionando suporte ao WSDL

O elemento de associaçã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 associação de transporte também deve exportar um URI de transporte correto em metadados. O código de exemplo a seguir é obtido do exemplo Transporte: UDP .

Exportação do WSDL

Para exportar informações de endereçamento, o UdpTransportBindingElement implementa a interface System.ServiceModel.Description.IWsdlExportExtension. 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 implementação UdpTransportBindingElement do método ExportEndpoint também exporta um URI de transporte, quando o ponto de extremidade usa uma associação SOAP:

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

Importação do 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 do WSDL:

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

  2. Adicione a seção de configuração para 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 à política

O elemento de associação personalizada pode exportar declarações de política na associação WSDL para um ponto de extremidade de serviço, para expressar os recursos desse elemento de associação. O código de exemplo a seguir é obtido do exemplo Transporte: UDP .

Exportação de políticas

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

Em IPolicyExportExtension.ExportPolicy, adicione uma declaração para UDP e outra declaração se o canal estiver no modo multicast. Isso ocorre porque o modo multicast afeta a forma como a pilha de comunicação é construída e, portanto, deve ser coordenado 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 associação de transporte personalizada são responsáveis por lidar com o endereçamento, a implementação System.ServiceModel.Description.IPolicyExportExtension no UdpTransportBindingElement também deve lidar com a exportação das devidas declarações de política de WS-Addressing, para indicar a versão do WS-Addressing usado.

AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);  

Importação de política

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 de nossa classe registrada (UdpBindingElementImporter). Em IPolicyImportExtension.ImportPolicy, examine as declarações no namespace apropriado e as processe para gerar o transporte e verificar se é multicast. Além disso, remova as declarações que o importador trata na lista de declarações de associação. Novamente, ao executar Svcutil.exe, há duas opções para integração:

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

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

Adição de um Importador de Associação Padrão Personalizada

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

Um importador de associaçã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 uma associaçã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;  
        }  
    }  
}  

Em geral, a implementação de um importador de associação padrão personalizado envolve a verificação das propriedades dos elementos de associaçã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 associação padrão é criar uma instância da associação padrão, propagar as propriedades dos elementos de associação para a instância de associação padrão compatível com a associação padrão e comparar os elementos de associação da associação padrão com os elementos de associação importados.