Compartilhar via


Como: escrever uma extensão para o ServiceContractGenerator

Este tópico descreve como escrever uma extensão para o ServiceContractGenerator. Isso pode ser feito implementando a interface IOperationContractGenerationExtension em um comportamento de operação ou implementando a interface IServiceContractGenerationExtension em um comportamento de contrato. Este tópico mostra como implementar a interface IServiceContractGenerationExtension em um comportamento de contrato.

O ServiceContractGenerator gera contratos de serviço, tipos de cliente e configurações de cliente das instâncias ServiceEndpoint, ContractDescription e Binding. Normalmente, você importa as instâncias ServiceEndpoint, ContractDescription e Binding de metadados de serviço e as usa para gerar código a fim de chamar o serviço. Neste exemplo, uma implementação IWsdlImportExtension é usada para processar anotações WSDL e, em seguida, adicionar extensões de geração de código aos contratos importados para gerar comentários sobre o código gerado.

Para gravar uma extensão para o ServiceContractGenerator

  1. Implementar IServiceContractGenerationExtension. Para modificar o contrato de serviço gerado, use a instância ServiceContractGenerationContext passada para o método GenerateContract(ServiceContractGenerationContext).

    public void GenerateContract(ServiceContractGenerationContext context)  
    {  
        Console.WriteLine("In generate contract.");  
        context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText));  
    }  
    
  2. Implemente IWsdlImportExtension na mesma classe. O método ImportContract(WsdlImporter, WsdlContractConversionContext) pode processar uma extensão WSDL específica (anotações WSDL nesse caso) adicionando uma extensão de geração de código à instância importada ContractDescription.

    public void ImportContract(WsdlImporter importer, WsdlContractConversionContext context)
    {
        // Contract documentation
        if (context.WsdlPortType.Documentation != null)
        {
            context.Contract.Behaviors.Add(new WsdlDocumentationImporter(context.WsdlPortType.Documentation));
        }
        // Operation documentation
        foreach (Operation operation in context.WsdlPortType.Operations)
        {
            if (operation.Documentation != null)
            {
                OperationDescription operationDescription = context.Contract.Operations.Find(operation.Name);
                if (operationDescription != null)
                {
                    operationDescription.Behaviors.Add(new WsdlDocumentationImporter(operation.Documentation));
                }
            }
        }
    }
    public void BeforeImport(ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, ICollection<XmlElement> policy)
    {
        Console.WriteLine("BeforeImport called.");
    }
    
    public void ImportEndpoint(WsdlImporter importer, WsdlEndpointConversionContext context)
    {
        Console.WriteLine("ImportEndpoint called.");
    }
    
  3. Adicione o importador WSDL à configuração do cliente.

    <metadata>  
      <wsdlImporters>  
        <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" />  
      </wsdlImporters>  
    </metadata>  
    
  4. No código do cliente, crie um MetadataExchangeClient e chame GetMetadata.

    var mexClient = new MetadataExchangeClient(metadataAddress);  
    mexClient.ResolveMetadataReferences = true;  
    MetadataSet metaDocs = mexClient.GetMetadata();  
    
  5. Criar um WsdlImporter e chamar ImportAllContracts.

    var importer = new WsdlImporter(metaDocs);
    System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();  
    
  6. Crie um ServiceContractGenerator e chame GenerateServiceContractType para cada contrato.

    var generator = new ServiceContractGenerator();  
    foreach (ContractDescription contract in contracts)  
    {  
       generator.GenerateServiceContractType(contract);  
    }  
    if (generator.Errors.Count != 0)  
       throw new Exception("There were errors during code compilation.");  
    
  7. GenerateContract(ServiceContractGenerationContext) é chamado automaticamente para cada comportamento de contrato em um determinado contrato que implementa IServiceContractGenerationExtension. Esse método pode modificar o ServiceContractGenerationContext passado. Neste exemplo, os comentários são adicionados.

Confira também