Share via


方法: ServiceContractGenerator の拡張を記述する

このトピックでは、ServiceContractGenerator の拡張を記述する方法について説明します。 これは、操作の動作に IOperationContractGenerationExtension インターフェイスを実装するか、コントラクトの動作に IServiceContractGenerationExtension インターフェイスを実装することで可能になります。 このトピックでは、IServiceContractGenerationExtension インターフェイスをコントラクト動作に実装する方法を説明します。

ServiceContractGenerator は、サービス コントラクト、クライアント型、およびクライアント構成を ServiceEndpointContractDescriptionBinding の各インターフェイスから生成します。 通常は、サービス メタデータから ServiceEndpointContractDescription、および Binding インスタンスをインポートし、これらのインスタンスを使用してサービスを呼び出すコードを生成します。 この例では、IWsdlImportExtension の実装を使用して WSDL 注釈を処理し、生成されたコードに関するコメントを生成するために、インポートしたコントラクトにコード生成拡張を追加します。

ServiceContractGenerator の拡張を記述するには

  1. IServiceContractGenerationExtensionを実装します。 生成されたサービス コントラクトを変更するには、ServiceContractGenerationContext メソッドに渡された GenerateContract(ServiceContractGenerationContext) インスタンスを使用します。

    public void GenerateContract(ServiceContractGenerationContext context)  
    {  
        Console.WriteLine("In generate contract.");  
        context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText));  
    }  
    
  2. 同じクラスに IWsdlImportExtension を実装します。 ImportContract(WsdlImporter, WsdlContractConversionContext) メソッドは、インポートされた ContractDescription インスタンスにコード生成拡張を追加することによって、特定の 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 を呼び出します。

    var mexClient = new MetadataExchangeClient(metadataAddress);  
    mexClient.ResolveMetadataReferences = true;  
    MetadataSet metaDocs = mexClient.GetMetadata();  
    
  5. WsdlImporter を作成して ImportAllContracts を呼び出します。

    var importer = new WsdlImporter(metaDocs);
    System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();  
    
  6. ServiceContractGenerator を作成して、コントラクトごとに GenerateServiceContractType を呼び出します。

    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) を実装する特定のコントラクトのコントラクト動作ごとに、IServiceContractGenerationExtension が自動的に呼び出されます。 その後、渡された ServiceContractGenerationContext をこのメソッドで変更できます。 この例では、コメントが追加されています。

関連項目