I have done several projects over the year that require me to produce auto generate source code, mainly to avoid repetitive code tasks, to accomplish this I have used tools similar to CodeSmith. A couple of weeks ago I was tasked with auto-generating code using the CodeDOM, I was actually surprised to find out that this kind of source building framework existed natively, you can create every imaginable object type inherent to the .NET stack. Here is a simple example:
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace samples = new CodeNamespace("Samples"); samples.Imports.Add(new CodeNamespaceImport("System")); CodeTypeDeclaration myclass = new CodeTypeDeclaration("Class1"); samples.Types.Add(myclass); CSharpCodeProvider provider = new CSharpCodeProvider(); string sourceFile = nameof(myclass ) + provider.FileExtension; using (StreamWriter sw = new StreamWriter(sourceFile, false)) { IndentedTextWriter tw = new IndentedTextWriter(sw, " "); provider.GenerateCodeFromCompileUnit(compileUnit, tw,new CodeGeneratorOptions()); tw.Close(); }
Now the above example is almost verbatim from MSDN, and actually outputs something like this, notice the misplaced using statement inside the names:
namespace Samples { using System; public class Class1 {} }
To avoid this you need to initially create a blank namespace and add your required using statements there, later we add both namespaces to our CompileUnit like this:
CodeCompileUnit compileUnit = new CodeCompileUnit(); CodeNamespace blankNamespaces = new CodeNamespace(); blankNamespaces.Imports.Add(new CodeNamespaceImport("System")); CodeNamespace samples = new CodeNamespace("Samples"); CodeTypeDeclaration myclass = new CodeTypeDeclaration("Class1"); samples.Types.Add(myclass); compileUnit.Namespaces.Add(blankNamespaces); // Add the blank using statement compileUnit.Namespaces.Add(samples); CSharpCodeProvider provider = new CSharpCodeProvider(); string sourceFile = nameof(myclass) + "." + provider.FileExtension; using (StreamWriter sw = new StreamWriter(sourceFile, false)) IndentedTextWriter tw = new IndentedTextWriter(sw, " "); provider.GenerateCodeFromCompileUnit(compileUnit, tw, new CodeGeneratorOptions()); tw.Close(); }
This leads to a more syntactically appropriate source file
using System; namespace Samples { public class Class1 {} }
Comments are closed.