Request: Option to generate seperate classfiles

Jul 3, 2009 at 4:48 PM

Yes, this involves a tremendous amount of work and will require application re-structuring.

Sep 10, 2009 at 3:24 PM

I completely disagree.  I have done this by altering the code, and did it in about 2 hours.  I am happy to share the code if you wish.

Sep 10, 2009 at 7:39 PM
Edited Sep 10, 2009 at 9:45 PM

Hey, I'm not the developer but send me the code I'll use it.

Sep 14, 2009 at 3:04 PM

The work for generating the file/s is done in the file GeneratorFacade.cs in the Libray project.  The code at present looks like this:

private Result Process(string outputFilePath)
        {
            #region Change CurrentDir for include schema resolution.

            string savedCurrentDir = Directory.GetCurrentDirectory();
            var inputFile = new FileInfo(GeneratorContext.GeneratorParams.InputFilePath);

            if (!inputFile.Exists)
            {
                var errorMessage = "Faild to generate code\n";
                errorMessage += "Exception :\n";
                errorMessage += string.Format("Input file {0} not exist", GeneratorContext.GeneratorParams.InputFilePath);
                return new Result(false, MessageType.Error, errorMessage);
            }

            if (inputFile.Directory != null) Directory.SetCurrentDirectory(inputFile.Directory.FullName);

            #endregion

            try
            {
                try
                {
//                    var codeOption = new CodeGeneratorOptions();
                    var result = Generator.Process(GeneratorContext.GeneratorParams);
                    if (!result.Success) return result;

                    var ns = result.Entity;
 
                    using (var outputStream = new StreamWriter(outputFilePath + ".tmp", false))
                        this.providerField.GenerateCodeFromNamespace(ns, outputStream, new CodeGeneratorOptions());
                }
                catch (Exception e)
                {
                    var errorMessage = "Failed to generate code\n";
                    errorMessage += "Exception :\n";
                    errorMessage += e.Message;

                    Debug.WriteLine("");
                    Debug.WriteLine("XSD2Code - ----------------------------------------------------------");
                    Debug.WriteLine("XSD2Code - " + e.Message);
                    Debug.WriteLine("XSD2Code - ----------------------------------------------------------");
                    Debug.WriteLine("");
                    return new Result(false, MessageType.Error, errorMessage);
                }

                var outputFile = new FileInfo(outputFilePath);
                if (outputFile.Exists)
                {
                    if ((outputFile.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                    {
                        var errorMessage = "Failed to generate code\n";
                        errorMessage += outputFilePath + " is write protect";
                        return new Result(false, MessageType.Error, errorMessage);
                    }
                }

                #region Insert tag for future generation

                using (var outputStream = new StreamWriter(outputFilePath, false))
                {


                    string commentStr = GeneratorContext.GeneratorParams.Language == GenerationLanguage.CSharp
                                            ? "// "
                                            : "'' ";

                    Assembly currentAssembly = Assembly.GetExecutingAssembly();
                    AssemblyName currentAssemblyName = currentAssembly.GetName();

                    outputStream.WriteLine(
                        "{0}------------------------------------------------------------------------------",
                            commentStr);
                    outputStream.WriteLine(string.Format("{0} <auto-generated>", commentStr));
                    
                    outputStream.WriteLine(string.Format("{0}   Generated by Xsd2Code. Version {1}", commentStr,
                                                  currentAssemblyName.Version));
                    
                    string optionsLine = string.Format("{0}   {1}", commentStr,
                                                       GeneratorContext.GeneratorParams.ToXmlTag());
                    outputStream.WriteLine(optionsLine);
                    
                    outputStream.WriteLine("{0} <auto-generated>", commentStr);

                    outputStream.WriteLine(
                            "{0}------------------------------------------------------------------------------",
                            commentStr);


                    #endregion

                    using (TextReader streamReader = new StreamReader(outputFilePath + ".tmp"))
                    {
                        string line;
                        while ((line = streamReader.ReadLine()) != null)
                        {
                            if (line.Trim() == "[System.SerializableAttribute()]" ||
                                line.Trim() == "[System.ComponentModel.DesignerCategoryAttribute(\"code\")]") continue;

                            if (GeneratorContext.GeneratorParams.DisableDebug) outputStream.WriteLine(line);
                            else
                            {
                                if (line.Trim() != "[System.Diagnostics.DebuggerStepThroughAttribute()]")
                                    outputStream.WriteLine(line);
                            }
                        }
                    }
                    outputStream.Close();                    
                }
                try
                {
                    var tempFile = new FileInfo(outputFilePath + ".tmp");
                    tempFile.Delete();
                }
                catch (Exception ex)
                {
                    return new Result(false, MessageType.Error, ex.Message);
                }
            }
            finally
            {
                Directory.SetCurrentDirectory(savedCurrentDir);
            }

            return new Result(true);
        }
            
Instead, alter the code to something like the following:
        private Result Process(string outputFilePath)
        {
            #region Change CurrentDir for include schema resolution.

            string savedCurrentDir = Directory.GetCurrentDirectory();
            var inputFile = new FileInfo(GeneratorContext.GeneratorParams.InputFilePath);

            if (!inputFile.Exists)
            {
                var errorMessage = "Faild to generate code\n";
                errorMessage += "Exception :\n";
                errorMessage += string.Format("Input file {0} not exist", GeneratorContext.GeneratorParams.InputFilePath);
                return new Result(false, MessageType.Error, errorMessage);
            }

            if (inputFile.Directory != null) 
                Directory.SetCurrentDirectory(inputFile.Directory.FullName);

            #endregion

            //var tempFile = outputFilePath + ".tmp";
            var path = Path.GetDirectoryName(outputFilePath);
            var tempPath = Path.Combine(path, "Temp");

            if(!Directory.Exists(tempPath))
                Directory.CreateDirectory(tempPath);
            
            try
            {
                try
                {
                    var result = Generator.Process(GeneratorContext.GeneratorParams);
                    if (!result.Success) return result;

                    var ns = result.Entity;

                    var options = new CodeGeneratorOptions();
                    var commentStr = GeneratorContext.GeneratorParams.Language == GenerationLanguage.CSharp
                                            ? "// "
                                            : "'' ";

                    var currentAssembly = Assembly.GetExecutingAssembly();
                    var currentAssemblyName = currentAssembly.GetName();

                    var info = FileVersionInfo.GetVersionInfo(currentAssembly.Location);
                    
                    var usings = new StringBuilder();

                    foreach(CodeNamespaceImport import in ns.Imports) {
                        usings.AppendFormat("using {0}", import.Namespace).AppendLine(";");
                    }

                    var header = string.Format(Resources.HeaderText, info.ProductName, currentAssemblyName.Version,
                                               info.LegalCopyright);
                    
                    var namespaceLine = string.Format("namespace {0} {{", ns.Name);

                    foreach (CodeTypeDeclaration codeType in ns.Types) {
                        
                        using(var outputStream = new StreamWriter(Path.Combine(tempPath, codeType.Name + ".cs"), false)) {
                            outputStream.WriteLine(header);
                            outputStream.WriteLine(usings.ToString());
                            outputStream.WriteLine(namespaceLine);

                            providerField.GenerateCodeFromType(codeType, outputStream, options);

                            outputStream.WriteLine();
                            outputStream.WriteLine("}");
                        }
                    }
                }
                catch (Exception e)
                {
                    var errorMessage = "Failed to generate code\n";
                    errorMessage += "Exception :\n";
                    errorMessage += e.Message;

                    Debug.WriteLine("");
                    Debug.WriteLine("XSD2Code - ----------------------------------------------------------");
                    Debug.WriteLine("XSD2Code - " + e.Message);
                    Debug.WriteLine("XSD2Code - ----------------------------------------------------------");
                    Debug.WriteLine("");
                    return new Result(false, MessageType.Error, errorMessage);
                }    
            }
            finally
            {
                Directory.SetCurrentDirectory(savedCurrentDir);
            }

            return new Result(true);
        }
If you have any problems with this let me know, as I do have some other changes elsewhere that may affect this, namely I do not generate a default constructor and initialise any fields.
This is largely as there is a bug in the system that means that nullable fields are initiated in the constuctor, which can lead to circular reference issues. 
I do not believe that a code gen tool needs to create the constructor anyway.  The whole point of a partial class is to let the end user suppliment the code as they see fit.