/// <summary> /// This method writes the generated code into a single file. /// </summary> private void WriteSingleCodeFile() { // Some assertions to make debugging easier. Debug.Assert(!string.IsNullOrEmpty(options.OutputLocation), "This action cannot be performed when output location is null or an empty string."); Debug.Assert(!string.IsNullOrEmpty(options.OutputFileName), "This action cannot be performed when output file name is null or an empty string"); CodeExtension.RefineCodeWithShortName(codeCompileUnit); CodeNamespace codeNamespace = CodeExtension.GenerateCode(codeCompileUnit); codeNamespace.Name = options.TargetNamespace; CodeCompileUnit tempUnit = new CodeCompileUnit(); tempUnit.Namespaces.Add(codeNamespace); // Get the destination file name. string fileName = CodeWriter.GetUniqueFileName(options.OutputLocation, options.OutputFileName, options.Language, options.OverwriteExistingFiles); // Create a StreamWriter for writing to the destination file. StreamWriter writer = new StreamWriter(fileName, false, Encoding.UTF8); try { // Write out the code to the destination file. provider.GenerateCodeFromCompileUnit(tempUnit, writer, codeGenerationOptions); // Flush all buffers in the writer. writer.Flush(); // Initialize generatedFileNames array to hold the one and only one // file we just generated. generatedCodeFileNames = new string[1]; // Finally add the file name to the generatedFileNames array. generatedCodeFileNames[0] = fileName; } catch (IOException e) { // Wrap the IOException in a CodeWriterException with little bit // more information. throw new CodeWriterException( string.Format("An error occurred while trying write to file {0}: {1}", fileName, e.Message), e); } finally { // No matter what happens, dispose the stream writer and release the unmanaged // resources. writer.Dispose(); } }
/// <summary> /// Generates the <see cref="CodeCompileUnit"/> based on the provide context. /// </summary> /// <param name="codeGeneratorContext">The code generator context.</param> public CodeCompileUnit GenerateDataContractCode(ICodeGeneratorContext codeGeneratorContext) { CodeGenOptions codeGenOptions = codeGeneratorContext.CodeGenOptions; XmlSchemas xmlSchemas = codeGeneratorContext.XmlSchemas; CodeNamespace codeNamespace = new CodeNamespace(); // Generate DataContracts const CodeGenerationOptions generationOptions = CodeGenerationOptions.GenerateProperties; var exporter = new XmlCodeExporter(codeNamespace); var importer = new XmlSchemaImporter(xmlSchemas, generationOptions, new ImportContext(new CodeIdentifiers(), false)); // TypeName to XmlSchemaType mapping IDictionary <string, XmlSchemaType> typeName2schemaTypeMapping = codeGeneratorContext.TypeName2schemaTypeMapping; IDictionary <XmlQualifiedName, string> elementName2TypeNameMapping = codeGeneratorContext.ElementName2TypeNameMapping; IDictionary <string, string> elementName2TargetNamespaceMapping = codeGeneratorContext.ElementName2TargetNamespaceMapping; foreach (XmlSchema schema in xmlSchemas) { foreach (XmlSchemaElement element in schema.Elements.Values) { XmlTypeMapping typeMapping = importer.ImportTypeMapping(element.QualifiedName); if (element.IsAbstract) { continue; } exporter.ExportTypeMapping(typeMapping); if (typeMapping.XsdTypeName == "anyType") { continue; // ignore no type element } if (string.IsNullOrWhiteSpace(typeMapping.XsdTypeName)) { throw new Exception("Cannot use anonymous type for Request/Response element: " + element.Name + "."); } typeName2schemaTypeMapping[typeMapping.XsdTypeName] = element.ElementSchemaType; elementName2TypeNameMapping[element.QualifiedName] = typeMapping.XsdTypeName; elementName2TargetNamespaceMapping[element.QualifiedName.Name] = schema.TargetNamespace; } foreach (XmlSchemaType complexType in schema.SchemaTypes.Values) { XmlTypeMapping typeMapping = importer.ImportSchemaType(complexType.QualifiedName); if (DataContractGenerator.CouldBeAnArray(complexType)) { continue; } exporter.ExportTypeMapping(typeMapping); typeName2schemaTypeMapping[typeMapping.TypeName] = complexType; } } if (codeNamespace.Types.Count == 0) { throw new Exception("No types were generated."); } CodeCompileUnit codeCompileUnit = CodeExtension.GenerateDataContractCode(xmlSchemas); CodeExtension.RefineCode(codeCompileUnit); codeNamespace = CodeExtension.GenerateCode(codeCompileUnit); codeGeneratorContext.CodeTypeMap = DataContractGenerator.BuildCodeTypeMap(codeNamespace); // Generate interface code string wsdlFile = codeGeneratorContext.CodeGenOptions.MetadataLocation; InterfaceContract interfaceContract = ServiceDescriptionEngine.GetInterfaceContract(wsdlFile); CodeTypeDeclaration codeType; CodeNamespaceImportCollection imports; this.buildInterfaceCode(codeGeneratorContext, interfaceContract, out codeType, out imports); imports.Add(new CodeNamespaceImport(Constants.C_SERVICE_STACK_COMMON_TYPES_NAMESPACE)); codeNamespace = new CodeNamespace(codeGenOptions.ClrNamespace); codeNamespace.Types.Add(codeType); foreach (CodeNamespaceImport @import in imports) { codeNamespace.Imports.Add(@import); } codeCompileUnit.Namespaces.Add(codeNamespace); codeCompileUnit.ImplementsBaijiSerialization(codeGeneratorContext); // Import SOA common type namespace before removing code types List <CodeNamespace> toBeRemovedNamespaces = new List <CodeNamespace>(); foreach (CodeNamespace @namespace in codeCompileUnit.Namespaces) { // Remove SOA common types since they have already been included in CSerivceStack DLL bool hasTypeRemoved = CodeExtension.RemoveSOACommonTypes(@namespace); if (hasTypeRemoved) { @namespace.Imports.Add(new CodeNamespaceImport(Constants.C_SERVICE_STACK_COMMON_TYPES_NAMESPACE)); } if (@namespace.Types.Count == 0) { toBeRemovedNamespaces.Add(@namespace); } } foreach (CodeNamespace @namespace in toBeRemovedNamespaces) { codeCompileUnit.Namespaces.Remove(@namespace); } foreach (CodeNamespace @namespace in codeCompileUnit.Namespaces) { if (@namespace.Name != codeNamespace.Name) { codeNamespace.Imports.Add(new CodeNamespaceImport(@namespace.Name)); } } CodeExtension.RemoveDefaultTypes(codeCompileUnit); if (codeGeneratorContext.CodeGenOptions.AddCustomRequestInterface) { DataContractGenerator.ImplementCustomInterface(codeGeneratorContext, codeCompileUnit); } return(codeCompileUnit); }