问题
When using a CodeCompileUnit to generate code via the CodeDOM, you can import namespaces by creating a CodeNamespace separate from the namespace in which you're defining your type(s). Using the Imports property allows you to add the namespaces you desire. If you add the CodeNamespace to the CodeCompile unit, the imports will appear at the top of the file generated by the CodeDOM.
For instance, using a CSharpCodeProvider to compile the following CodeDOM graph:
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace importsNamespace = new CodeNamespace {Imports = {new CodeNamespaceImport("System"), new CodeNamespaceImport("System.Collections.Generic"), new CodeNamespaceImport("System.Linq")}};
CodeNamespace typeNamespace = new CodeNamespace("MyTypeNamespace");
compileUnit.Namespaces.Add(importsNamespace);
compileUnit.Namespaces.Add(typeNamespace);
will generate
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.269
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyTypeNamespace {
}
The CodeSnippetCompileUnit allows you to compile type definitions which have been entered as a string. For instance, the string "public class TestClass {}" can be used as the Value for a CodeSnippetCompileUnit. Using the same code as above with a CodeSnippetCompileUnit:
const string testClassCodeString = "public class TestClass {}";
CodeSnippetCompileUnit snippetCompileUnit = new CodeSnippetCompileUnit {Value = testClassCodeString};
CodeNamespace importsNamespace = new CodeNamespace {Imports = {new CodeNamespaceImport("System"), new CodeNamespaceImport("System.Collections.Generic"), new CodeNamespaceImport("System.Linq")}};
CodeNamespace typeNamespace = new CodeNamespace("MyTypeNamespace");
compileUnit.Namespaces.Add(importsNamespace);
compileUnit.Namespaces.Add(typeNamespace);
will generate a file which contains only:
public class TestClass {}
How can you enclose this type in a namespace, or import namespaces to the file generated from a CodeSnippetCompileUnit?
回答1:
Even though CodeSnippetCompileUnit is derived from CodeCompileUnit, the compiler ignores the Namespaces property when generating code from the CodeDOM graph. Code generated from the CodeSnippetCompileUnit contains only the string that is in the Value property of the object.
If you have a context-free code snippet, your only option to import namespaces or enclose the snippet in a namespace is to modify the string before setting the Value of the CodeSnippetCompileUnit.
An example using the code in the question above as a starting place:
string namespaceString = "MyTypeNamespace";
string codeString = "public class TestClass {}";
string snippetValue = string.Format(@"
using System;
using System.Collections.Generic;
using System.Linq;
namespace {0}
{{
{1}
}}", namespaceString, codeString, Environment.NewLine);
var snippetCompileUnit = new CodeSnippetCompileUnit {Value = snippetValue};
This will generate:
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyTypeNamespace
{
public class TestClass {}
}
来源:https://stackoverflow.com/questions/11544634/import-namespaces-in-a-codesnippetcompileunit