Condividi tramite


Procedura: scrivere un'estensione per ServiceContractGenerator

In questo argomento viene illustrato come scrivere un'estensione per la classe ServiceContractGenerator. A tal fine è necessario implementare l'interfaccia IOperationContractGenerationExtension su un comportamento di operazione oppure l'interfaccia IServiceContractGenerationExtension su un comportamento di contratto. In questo argomento viene illustrato come implementare l'interfaccia IServiceContractGenerationExtension in un comportamento di contratto.

ServiceContractGenerator genera contratti di servizio, tipi di client e configurazioni client da istanze ServiceEndpoint, ContractDescription e Binding. In genere, si importano istanze ServiceEndpoint, ContractDescription e Binding da metadati del servizio e si utilizzano quindi tali istanze per generare il codice necessario per chiamare il servizio. In questo esempio viene utilizzata un'implementazione IWsdlImportExtension per elaborare annotazioni WSDL e aggiungere estensioni di generazione del codice ai contratti importati al fine di generare commenti sul codice generato.

Scrivere un'estensione per ServiceContractGenerator

  1. Implementare IServiceContractGenerationExtension. Per modificare il contratto di servizio generato, utilizzare l'istanza ServiceContractGenerationContext passata nel metodo GenerateContract(ServiceContractGenerationContext).

    public void GenerateContract(ServiceContractGenerationContext context)  
    {  
        Console.WriteLine("In generate contract.");  
        context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText));  
    }  
    
  2. Implementare IWsdlImportExtension nella stessa classe. Il metodo ImportContract(WsdlImporter, WsdlContractConversionContext) consente di elaborare un'estensione WSDL specifica (annotazioni WSDL in questo caso) mediante l'aggiunta di un'estensione di generazione del codice all'istanza ContractDescription importata.

    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. Aggiungere l'unità di importazione WSDL alla configurazione del client.

    <metadata>  
      <wsdlImporters>  
        <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" />  
      </wsdlImporters>  
    </metadata>  
    
  4. Nel codice client creare MetadataExchangeClient e chiamare GetMetadata.

    var mexClient = new MetadataExchangeClient(metadataAddress);  
    mexClient.ResolveMetadataReferences = true;  
    MetadataSet metaDocs = mexClient.GetMetadata();  
    
  5. Creare un WsdlImporter e chiamare ImportAllContracts.

    var importer = new WsdlImporter(metaDocs);
    System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();  
    
  6. Creare ServiceContractGenerator e chiamare GenerateServiceContractType per ogni contratto.

    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) viene chiamato automaticamente per ogni comportamento del contratto in un determinato contratto che implementa IServiceContractGenerationExtension. Questo metodo può quindi modificare l'oggetto ServiceContractGenerationContext passato. In questo esempio vengono aggiunti commenti.

Vedi anche