Поделиться через


Практическое руководство. Разработка расширения для ServiceContractGenerator

В этом разделе описывается, как разработать расширение для ServiceContractGenerator. Это можно сделать путем реализации интерфейса IOperationContractGenerationExtension для поведения операции или интерфейса IServiceContractGenerationExtension для поведения контракта. Здесь показана реализация интерфейса IServiceContractGenerationExtension для поведения контракта.

ServiceContractGenerator создает контракты службы, типы клиента и конфигурации клиента из экземпляров ServiceEndpoint, ContractDescription и Binding. Как правило, экземпляры ServiceEndpoint, ContractDescription и 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) может обработать определенное расширение WSDL (в данном случае заметки WSDL), добавив расширение создания кода в импортированный экземпляр 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. Добавьте средство импорта 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. В данном примере добавлены комментарии.

См. также