방법: ServiceContractGenerator에 대한 확장 쓰기
이 항목에서는 ServiceContractGenerator에 대한 확장을 쓰는 방법에 대해 설명합니다. 이 작업을 수행하려면 작업 동작에 IOperationContractGenerationExtension 인터페이스를 구현하거나 계약 동작에 IServiceContractGenerationExtension 인터페이스를 구현합니다. 다음 항목에서는 계약 동작에서 IServiceContractGenerationExtension 인터페이스를 구현하는 방법을 보여 줍니다.
ServiceContractGenerator는 ServiceEndpoint, ContractDescription 및 Binding 인스턴스에서 서비스 계약, 클라이언트 형식 및 클라이언트 구성을 생성합니다. 일반적으로 서비스 메타데이터에서 ServiceEndpoint, ContractDescription 및 Binding 인스턴스를 가져온 다음 이러한 인스턴스를 사용하여 서비스를 호출할 코드를 생성합니다. 이 예제에서 IWsdlImportExtension 구현은 생성된 코드에 주석을 생성하기 위해 WSDL 주석을 처리한 다음 가져온 계약에 코드 생성 확장을 추가하는 데 사용됩니다.
ServiceContractGenerator에 대한 확장을 쓰려면
IServiceContractGenerationExtension를 구현해야 합니다. 생성된 서비스 계약을 수정하려면 ServiceContractGenerationContext 메서드로 전달된 GenerateContract(ServiceContractGenerationContext) 인스턴스를 사용합니다.
public void GenerateContract(ServiceContractGenerationContext context) { Console.WriteLine("In generate contract."); context.ContractType.Comments.AddRange(Formatter.FormatComments(commentText)); }
같은 클래스에서 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."); }
클라이언트 구성에 WSDL 가져오기를 추가합니다.
<metadata> <wsdlImporters> <extension type="Microsoft.WCF.Documentation.WsdlDocumentationImporter, WsdlDocumentation" /> </wsdlImporters> </metadata>
클라이언트 코드에
MetadataExchangeClient
를 만들고GetMetadata
를 호출합니다.var mexClient = new MetadataExchangeClient(metadataAddress); mexClient.ResolveMetadataReferences = true; MetadataSet metaDocs = mexClient.GetMetadata();
WsdlImporter
를 만들고ImportAllContracts
를 호출합니다.var importer = new WsdlImporter(metaDocs); System.Collections.ObjectModel.Collection<ContractDescription> contracts = importer.ImportAllContracts();
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.");
GenerateContract(ServiceContractGenerationContext)는 IServiceContractGenerationExtension을 구현하는 제공된 계약에서 각 계약 동작에 대해 자동으로 호출됩니다. 그런 다음 이 메서드는 전달된 ServiceContractGenerationContext를 수정할 수 있습니다. 이 예제에서는 주석이 추가되었습니다.