如何:编写 ServiceContractGenerator 的扩展

2025-04-30 05:15:02
推荐回答(1个)
回答1:

这可以通过对操作行为实现 IOperationContractGenerationExtension 接口或者对协定行为实现 IServiceContractGenerationExtension 接口来完成。本主题演示如何对协定行为实现 IServiceContractGenerationExtension 接口。ServiceContractGenerator 从ServiceEndpoint、ContractDescription 和Binding 实例生成服务协定、客户端类型和客户端配置。通常,需要先从服务元数据导入 ServiceEndpoint、ContractDescription 和Binding 实例,然后使用这些实例生成调用服务的代码。在本示例中,IWsdlImportExtension 实现用于处理 WSDL 批注,然后将代码生成扩展添加到导入的协定中,以生成对已生成代码的注释。编写ServiceContractGenerator 的扩展实现IServiceContractGenerationExtension。若要修改已生成的服务协定,请使用传入 GenerateContract 方法的 ServiceContractGenerationContext 实例。 public void GenerateContract(ServiceContractGenerationContext context) { Console.WriteLine("In generate contract."); context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText)); } 在同一个类上实现 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 policy) { Console.WriteLine("BeforeImport called."); } public void ImportEndpoint(WsdlImporter importer, WsdlEndpointConversionContext context) { Console.WriteLine("ImportEndpoint called."); } 将WSDL 导入程序添加到客户端配置中。 在客户端代码中,创建一个 MetadataExchangeClient 并调用 GetMetadata。 MetadataExchangeClient mexClient = new MetadataExchangeClient(metadataAddress); mexClient.ResolveMetadataReferences = true; MetadataSet metaDocs = mexClient.GetMetadata(); 创建一个 WsdlImporter 并调用 ImportAllContracts。 WsdlImporter importer = new WsdlImporter(metaDocs); System.Collections.ObjectModel.Collection contracts = importer.ImportAllContracts(); 创建一个 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."); 会为实现 IServiceContractGenerationExtension 的给定协定上的每个协定行为自动调用 GenerateContract。然后,此方法可以修改传入的 ServiceContractGenerationContext。在本示例中,添加了注释。另请参见任务如何:导入自定义 WSDL概念元数据