如何:编写 ServiceContractGenerator 的扩展

本主题描述如何编写 ServiceContractGenerator 的扩展。这可以通过对操作行为实现 IOperationContractGenerationExtension 接口或者对协定行为实现 IServiceContractGenerationExtension 接口来完成。本主题演示如何对协定行为实现 IServiceContractGenerationExtension 接口。

ServiceContractGeneratorServiceEndpointContractDescriptionBinding 实例生成服务协定、客户端类型和客户端配置。通常,需要先从服务元数据导入 ServiceEndpointContractDescriptionBinding 实例,然后使用这些实例生成调用服务的代码。在本示例中,IWsdlImportExtension 实现用于处理 WSDL 批注,然后将代码生成扩展添加到导入的协定中,以生成对已生成代码的注释。

编写 ServiceContractGenerator 的扩展

  1. 实现 IServiceContractGenerationExtension。若要修改已生成的服务协定,请使用传入 GenerateContract 方法的 ServiceContractGenerationContext 实例。

    public void GenerateContract(ServiceContractGenerationContext context)
    {
        Console.WriteLine("In generate contract.");
    context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText));
    }
    
  2. 在同一个类上实现 IWsdlImportExtension。通过将代码生成扩展添加到导入的 ContractDescription 实例,ImportContract 方法可以处理特定的 WSDL 扩展(此例中为 WSDL 批注)。

    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. 将 WSDL 导入程序添加到客户端配置中。

    <metadata>
      <wsdlImporters>
        <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" />
      </wsdlImporters>
    </metadata>
    
  4. 在客户端代码中,创建一个 MetadataExchangeClient 并调用 GetMetadata

                MetadataExchangeClient mexClient = new MetadataExchangeClient(metadataAddress);
                mexClient.ResolveMetadataReferences = true;
                MetadataSet metaDocs = mexClient.GetMetadata();
    
  5. 创建一个 WsdlImporter 并调用 ImportAllContracts

    WsdlImporter importer = new WsdlImporter(metaDocs);            System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();
    
  6. 创建一个 ServiceContractGenerator 并为每个协定调用 GenerateServiceContractType

    ServiceContractGenerator 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. 会为实现 IServiceContractGenerationExtension 的给定协定上的每个协定行为自动调用 GenerateContract。然后,此方法可以修改传入的 ServiceContractGenerationContext。在本示例中,添加了注释。

另请参见

任务

如何:导入自定义 WSDL

概念

元数据