Freigeben über


Vorgehensweise: Schreiben einer Erweiterung für die ServiceContractGenerator-Klasse

In diesem Thema wird beschrieben, wie Sie eine Erweiterung für den ServiceContractGenerator schreiben können. Dies kann durch Implementieren der IOperationContractGenerationExtension-Schnittstelle für ein Vorgangsverhalten oder Implementieren der IServiceContractGenerationExtension-Schnittstelle für ein Vertragsverhalten geschehen. In diesem Thema wird gezeigt, wie die IServiceContractGenerationExtension-Schnittstelle in einem Vertragsverhalten implementiert wird.

Der ServiceContractGenerator erstellt aus ServiceEndpoint-Instanzen, ContractDescription-Instanzen und Binding-Instanzen Dienstverträge, Clienttypen und Clientkonfigurationen. Normalerweise importieren Sie ServiceEndpoint-Instanzen, ContractDescription-Instanzen und Binding-Instanzen aus Dienstmetadaten und verwenden dann diese Instanzen, um den Code zum Aufrufen des Dienstes zu schreiben. In diesem Beispiel wird eine IWsdlImportExtension-Implementierung zur Verarbeitung von WSDL-Anmerkungen verwendet. Dann werden Codegenerierungserweiterungen in die importierten Verträge eingefügt, um Kommentare zu dem generierten Code zu erstellen.

So schreiben Sie eine Erweiterung für den ServiceContractGenerator

  1. Implementieren Sie IServiceContractGenerationExtension. Verwenden Sie zum Bearbeiten des generierten Dienstvertrags die ServiceContractGenerationContext-Instanz, die an die GenerateContract(ServiceContractGenerationContext)-Methode weitergegeben wurde.

    public void GenerateContract(ServiceContractGenerationContext context)  
    {  
        Console.WriteLine("In generate contract.");  
        context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText));  
    }  
    
  2. Implementieren Sie IWsdlImportExtension für die gleiche Klasse. Mit der ImportContract(WsdlImporter, WsdlContractConversionContext)-Methode kann eine bestimmte WSDL-Erweiterung (in diesem Fall WSDL-Anmerkungen) verarbeitet werden, indem eine Codegenerierungserweiterung der importierten ContractDescription-Instanz hinzugefügt wird.

    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. Fügen Sie den WSDL-Importer in Ihre Clientkonfiguration ein.

    <metadata>  
      <wsdlImporters>  
        <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" />  
      </wsdlImporters>  
    </metadata>  
    
  4. Erstellen Sie im Clientcode einen MetadataExchangeClient, und rufen Sie GetMetadata auf.

    var mexClient = new MetadataExchangeClient(metadataAddress);  
    mexClient.ResolveMetadataReferences = true;  
    MetadataSet metaDocs = mexClient.GetMetadata();  
    
  5. Erstellen Sie einen WsdlImporter, und rufen Sie ImportAllContracts auf.

    var importer = new WsdlImporter(metaDocs);
    System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();  
    
  6. Erstellen Sie einen ServiceContractGenerator, und rufen Sie den GenerateServiceContractType für jeden Vertrag auf.

    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) wird automatisch für jedes Vertragsverhalten für einen bestimmten Vertrag, der IServiceContractGenerationExtension implementiert, aufgerufen. Diese Methode kann dann den übergebenen ServiceContractGenerationContext ändern. In diesem Beispiel werden Kommentare hinzugefügt.

Siehe auch