如何:为 CodeDOM 生成的应用程序创建 XML 文档文件

CodeDOM 可用于创建生成 XML 文档的代码。 该进程包括创建包含 XML 文档注释的 CodeDOM 关系图、生成代码和通过创建 XML 文档输出的编译器选项编译生成的代码。

创建包含 XML 文档注释的 CodeDOM 关系图

  1. 为示例应用程序创建包含 CodeDOM 关系图的 CodeCompileUnit

  2. 使用 CodeCommentStatement 构造函数(docComment 参数设置为 true)创建 XML 文档注释元素和文本。

    Dim class1 As New CodeTypeDeclaration("Class1")
    
    class1.Comments.Add(New CodeCommentStatement("<summary>", True))
    class1.Comments.Add(New CodeCommentStatement( _
        "Create a Hello World application.", True))
    class1.Comments.Add(New CodeCommentStatement( _
        "<seealso cref=" & ControlChars.Quote & "Class1.Main" & _
        ControlChars.Quote & "/>", True))
    class1.Comments.Add(New CodeCommentStatement("</summary>", True))
    
    ' Add the new type to the namespace type collection.
    samples.Types.Add(class1)
    
    ' Declare a new code entry point method.
    Dim start As New CodeEntryPointMethod()
    start.Comments.Add(New CodeCommentStatement("<summary>", True))
    start.Comments.Add(New CodeCommentStatement( _
        "Main method for HelloWorld application.", True))
    start.Comments.Add(New CodeCommentStatement( _
        "<para>Add a new paragraph to the description.</para>", True))
    start.Comments.Add(New CodeCommentStatement("</summary>", True))
    
    CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");
    
    class1.Comments.Add(new CodeCommentStatement("<summary>", true));
    class1.Comments.Add(new CodeCommentStatement(
        "Create a Hello World application.", true));
    class1.Comments.Add(new CodeCommentStatement(
        @"<seealso cref=" + '"' + "Class1.Main" + '"' + "/>", true));
    class1.Comments.Add(new CodeCommentStatement("</summary>", true));
    
    // Add the new type to the namespace type collection.
    samples.Types.Add(class1);
    
    // Declare a new code entry point method.
    CodeEntryPointMethod start = new CodeEntryPointMethod();
    start.Comments.Add(new CodeCommentStatement("<summary>", true));
    start.Comments.Add(new CodeCommentStatement(
        "Main method for HelloWorld application.", true));
    start.Comments.Add(new CodeCommentStatement(
        @"<para>Add a new paragraph to the description.</para>", true));
    start.Comments.Add(new CodeCommentStatement("</summary>", true));
    

从 CodeCompileUnit 生成代码

  • 使用 GenerateCodeFromCompileUnit 方法生成代码并创建要编译的源文件。

    
    Dim sourceFile As New StreamWriter(sourceFileName)
    
    LogMessage("Generating code...")
    provider.GenerateCodeFromCompileUnit(cu, sourceFile, Nothing)
    sourceFile.Close()
    
    StreamWriter sourceFile = new StreamWriter(sourceFileName);
    provider.GenerateCodeFromCompileUnit(cu, sourceFile, null);
    sourceFile.Close();
    

编译代码和生成文档文件

  • /doc 编译器选项添加到 CompilerParameters 对象的 CompilerOptions 属性中,然后将该对象传递给 CompileAssemblyFromFile 方法,以便在编译代码后创建 XML 文档文件。

    Dim opt As New CompilerParameters(New String() {"System.dll"})
    opt.GenerateExecutable = True
    opt.OutputAssembly = "HelloWorld.exe"
    opt.TreatWarningsAsErrors = True
    opt.IncludeDebugInformation = True
    opt.GenerateInMemory = True
    opt.CompilerOptions = "/doc"
    
    Dim results As CompilerResults
    
    LogMessage(("Compiling with " & providerName))
    results = provider.CompileAssemblyFromFile(opt, sourceFileName)
    
    CompilerParameters opt = new CompilerParameters(new string[]{
                              "System.dll" });
    opt.GenerateExecutable = true;
    opt.OutputAssembly = "HelloWorld.exe";
    opt.TreatWarningsAsErrors = true;
    opt.IncludeDebugInformation = true;
    opt.GenerateInMemory = true;
    opt.CompilerOptions = "/doc:HelloWorldDoc.xml";
    
    CompilerResults results;
    
    LogMessage("Compiling with " + providerName);
    results = provider.CompileAssemblyFromFile(opt, sourceFileName);
    

示例

下面的代码示例创建了一个包含文档注释的 CodeDOM 关系图,然后从该关系图生成一个代码文件,之后编译了该文件并创建了一个关联的 XML 文档文件。

Imports System
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.IO
Imports System.Text.RegularExpressions



Class Program
    Private Shared providerName As String = "vb"
    Private Shared sourceFileName As String = "test.vb"

    Shared Sub Main(ByVal args() As String)
        Dim provider As CodeDomProvider = _
            CodeDomProvider.CreateProvider(providerName)

        LogMessage("Building CodeDOM graph...")

        Dim cu As New CodeCompileUnit()

        cu = BuildHelloWorldGraph()


        Dim sourceFile As New StreamWriter(sourceFileName)

        LogMessage("Generating code...")
        provider.GenerateCodeFromCompileUnit(cu, sourceFile, Nothing)
        sourceFile.Close()

        Dim opt As New CompilerParameters(New String() {"System.dll"})
        opt.GenerateExecutable = True
        opt.OutputAssembly = "HelloWorld.exe"
        opt.TreatWarningsAsErrors = True
        opt.IncludeDebugInformation = True
        opt.GenerateInMemory = True
        opt.CompilerOptions = "/doc"

        Dim results As CompilerResults

        LogMessage(("Compiling with " & providerName))
        results = provider.CompileAssemblyFromFile(opt, sourceFileName)

        OutputResults(results)
        If results.NativeCompilerReturnValue <> 0 Then
            LogMessage("")
            LogMessage("Compilation failed.")
        Else
            LogMessage("")
            LogMessage("Demo completed successfully.")
        End If
        File.Delete(sourceFileName)

    End Sub 'Main


    ' Build a Hello World program graph using 
    ' System.CodeDom types.
    Public Shared Function BuildHelloWorldGraph() As CodeCompileUnit
        ' Create a new CodeCompileUnit to contain 
        ' the program graph.
        Dim compileUnit As New CodeCompileUnit()

        ' Declare a new namespace called Samples.
        Dim samples As New CodeNamespace("Samples")
        ' Add the new namespace to the compile unit.
        compileUnit.Namespaces.Add(samples)

        ' Add the new namespace import for the System namespace.
        samples.Imports.Add(New CodeNamespaceImport("System"))

        ' Declare a new type called Class1.
        Dim class1 As New CodeTypeDeclaration("Class1")

        class1.Comments.Add(New CodeCommentStatement("<summary>", True))
        class1.Comments.Add(New CodeCommentStatement( _
            "Create a Hello World application.", True))
        class1.Comments.Add(New CodeCommentStatement( _
            "<seealso cref=" & ControlChars.Quote & "Class1.Main" & _
            ControlChars.Quote & "/>", True))
        class1.Comments.Add(New CodeCommentStatement("</summary>", True))

        ' Add the new type to the namespace type collection.
        samples.Types.Add(class1)

        ' Declare a new code entry point method.
        Dim start As New CodeEntryPointMethod()
        start.Comments.Add(New CodeCommentStatement("<summary>", True))
        start.Comments.Add(New CodeCommentStatement( _
            "Main method for HelloWorld application.", True))
        start.Comments.Add(New CodeCommentStatement( _
            "<para>Add a new paragraph to the description.</para>", True))
        start.Comments.Add(New CodeCommentStatement("</summary>", True))
        ' Create a type reference for the System.Console class.
        Dim csSystemConsoleType As New CodeTypeReferenceExpression( _
            "System.Console")

        ' Build a Console.WriteLine statement.
        Dim cs1 As New CodeMethodInvokeExpression(csSystemConsoleType, _
            "WriteLine", New CodePrimitiveExpression("Hello World!"))

        ' Add the WriteLine call to the statement collection.
        start.Statements.Add(cs1)

        ' Build another Console.WriteLine statement.
        Dim cs2 As New CodeMethodInvokeExpression(csSystemConsoleType, _
            "WriteLine", New CodePrimitiveExpression( _
            "Press the ENTER key to continue."))

        ' Add the WriteLine call to the statement collection.
        start.Statements.Add(cs2)

        ' Build a call to System.Console.ReadLine.
        Dim csReadLine As New CodeMethodInvokeExpression( _
            csSystemConsoleType, "ReadLine")

        ' Add the ReadLine statement.
        start.Statements.Add(csReadLine)

        ' Add the code entry point method to
        ' the Members collection of the type.
        class1.Members.Add(start)

        Return compileUnit

    End Function 'BuildHelloWorldGraph

    Shared Sub LogMessage(ByVal [text] As String)
        Console.WriteLine([text])

    End Sub 'LogMessage


    Shared Sub OutputResults(ByVal results As CompilerResults)
        LogMessage(("NativeCompilerReturnValue=" & _
            results.NativeCompilerReturnValue.ToString()))
        Dim s As String
        For Each s In results.Output
            LogMessage(s)
        Next s

    End Sub 'OutputResults
End Class 'Program
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Text.RegularExpressions;

namespace BasicCodeDomApp
{
    class Program
    {
        static string providerName = "cs";
        static string sourceFileName = "test.cs";
        static void Main(string[] args)
        {
            CodeDomProvider provider = 
                CodeDomProvider.CreateProvider(providerName);

            LogMessage("Building CodeDOM graph...");

            CodeCompileUnit cu = new CodeCompileUnit();

            cu = BuildHelloWorldGraph();

            StreamWriter sourceFile = new StreamWriter(sourceFileName);
            provider.GenerateCodeFromCompileUnit(cu, sourceFile, null);
            sourceFile.Close();

            CompilerParameters opt = new CompilerParameters(new string[]{
                                      "System.dll" });
            opt.GenerateExecutable = true;
            opt.OutputAssembly = "HelloWorld.exe";
            opt.TreatWarningsAsErrors = true;
            opt.IncludeDebugInformation = true;
            opt.GenerateInMemory = true;
            opt.CompilerOptions = "/doc:HelloWorldDoc.xml";

            CompilerResults results;

            LogMessage("Compiling with " + providerName);
            results = provider.CompileAssemblyFromFile(opt, sourceFileName);

            OutputResults(results);
            if (results.NativeCompilerReturnValue != 0)
            {
                LogMessage("");
                LogMessage("Compilation failed.");
            }
            else
            {
                LogMessage("");
                LogMessage("Demo completed successfully.");
            }
            File.Delete(sourceFileName);
        }

        // Build a Hello World program graph using 
        // System.CodeDom types.
        public static CodeCompileUnit BuildHelloWorldGraph()
        {
            // Create a new CodeCompileUnit to contain 
            // the program graph.
            CodeCompileUnit compileUnit = new CodeCompileUnit();

            // Declare a new namespace called Samples.
            CodeNamespace samples = new CodeNamespace("Samples");
            // Add the new namespace to the compile unit.
            compileUnit.Namespaces.Add(samples);

            // Add the new namespace import for the System namespace.
            samples.Imports.Add(new CodeNamespaceImport("System"));

            // Declare a new type called Class1.
            CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");

            class1.Comments.Add(new CodeCommentStatement("<summary>", true));
            class1.Comments.Add(new CodeCommentStatement(
                "Create a Hello World application.", true));
            class1.Comments.Add(new CodeCommentStatement(
                @"<seealso cref=" + '"' + "Class1.Main" + '"' + "/>", true));
            class1.Comments.Add(new CodeCommentStatement("</summary>", true));

            // Add the new type to the namespace type collection.
            samples.Types.Add(class1);

            // Declare a new code entry point method.
            CodeEntryPointMethod start = new CodeEntryPointMethod();
            start.Comments.Add(new CodeCommentStatement("<summary>", true));
            start.Comments.Add(new CodeCommentStatement(
                "Main method for HelloWorld application.", true));
            start.Comments.Add(new CodeCommentStatement(
                @"<para>Add a new paragraph to the description.</para>", true));
            start.Comments.Add(new CodeCommentStatement("</summary>", true));

            // Create a type reference for the System.Console class.
            CodeTypeReferenceExpression csSystemConsoleType = 
                new CodeTypeReferenceExpression("System.Console");

            // Build a Console.WriteLine statement.
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine",
                new CodePrimitiveExpression("Hello World!"));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs1);

            // Build another Console.WriteLine statement.
            CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine", new CodePrimitiveExpression(
                "Press the ENTER key to continue."));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs2);

            // Build a call to System.Console.ReadLine.
            CodeMethodInvokeExpression csReadLine = 
                new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

            // Add the ReadLine statement.
            start.Statements.Add(csReadLine);

            // Add the code entry point method to
            // the Members collection of the type.
            class1.Members.Add(start);

            return compileUnit;
        }
        static void LogMessage(string text)
        {
            Console.WriteLine(text);
        }

        static void OutputResults(CompilerResults results)
        {
            LogMessage("NativeCompilerReturnValue=" +
                results.NativeCompilerReturnValue.ToString());
            foreach (string s in results.Output)
            {
                LogMessage(s);
            }
        }
    }
}

该代码示例在 HelloWorldDoc.xml 文件中创建了下面的 XML 文档。

<?xml version="1.0" ?> 
<doc>
  <assembly>
    <name>HelloWorld</name> 
  </assembly>
  <members>
    <member name="T:Samples.Class1">
      <summary>
        Create a Hello World application. 
        <seealso cref="M:Samples.Class1.Main" /> 
      </summary>
    </member>
    <member name="M:Samples.Class1.Main">
      <summary>
        Main method for HelloWorld application. 
        <para>Add a new paragraph to the description.</para> 
      </summary>
    </member>
  </members>
</doc>

编译代码

  • 要成功执行此代码示例,就需要设置 FullTrust 权限。

请参见

参考

XML 文档注释(C# 编程指南)

概念

使用 XML 将代码文档化 (Visual Basic)

其他资源

XML Documentation (Visual C++)