Como: escrever uma extensão para o ServiceContractGenerator
Este tópico descreve como escrever uma extensão para o ServiceContractGenerator. Isso pode ser feito implementando a interface IOperationContractGenerationExtension em um comportamento de operação ou implementando a interface IServiceContractGenerationExtension em um comportamento de contrato. Este tópico mostra como implementar a interface IServiceContractGenerationExtension em um comportamento de contrato.
O ServiceContractGenerator gera contratos de serviço, tipos de cliente e configurações de cliente das instâncias ServiceEndpoint, ContractDescription e Binding. Normalmente, você importa as instâncias ServiceEndpoint, ContractDescription e Binding de metadados de serviço e as usa para gerar código a fim de chamar o serviço. Neste exemplo, uma implementação IWsdlImportExtension é usada para processar anotações WSDL e, em seguida, adicionar extensões de geração de código aos contratos importados para gerar comentários sobre o código gerado.
Para gravar uma extensão para o ServiceContractGenerator
Implementar IServiceContractGenerationExtension. Para modificar o contrato de serviço gerado, use a instância ServiceContractGenerationContext passada para o método GenerateContract(ServiceContractGenerationContext).
public void GenerateContract(ServiceContractGenerationContext context) { Console.WriteLine("In generate contract."); context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText)); }
Implemente IWsdlImportExtension na mesma classe. O método ImportContract(WsdlImporter, WsdlContractConversionContext) pode processar uma extensão WSDL específica (anotações WSDL nesse caso) adicionando uma extensão de geração de código à instância importada 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."); }
Adicione o importador WSDL à configuração do cliente.
<metadata> <wsdlImporters> <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" /> </wsdlImporters> </metadata>
No código do cliente, crie um
MetadataExchangeClient
e chameGetMetadata
.var mexClient = new MetadataExchangeClient(metadataAddress); mexClient.ResolveMetadataReferences = true; MetadataSet metaDocs = mexClient.GetMetadata();
Criar um
WsdlImporter
e chamarImportAllContracts
.var importer = new WsdlImporter(metaDocs); System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();
Crie um
ServiceContractGenerator
e chameGenerateServiceContractType
para cada contrato.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.");
GenerateContract(ServiceContractGenerationContext) é chamado automaticamente para cada comportamento de contrato em um determinado contrato que implementa IServiceContractGenerationExtension. Esse método pode modificar o ServiceContractGenerationContext passado. Neste exemplo, os comentários são adicionados.