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 SampleProfileUdpBindingConfigurationElement
de StandardBindingElement. O SampleProfileUdpBindingConfigurationElement
tem propriedades que correspondem às propriedades em SampleProfileUdpBinding
e 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:
Aponte Svcutil.exe para o arquivo de configuração usando o arquivo /SvcutilConfig:<file>.
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:
Aponte Svcutil.exe para o nosso arquivo de configuração usando o /SvcutilConfig:<file>.
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 SampleProfileUdpBinding
UdpBindingElementImporter
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.