如何将导入的命名空间提供给CompileAssemblyFromSource

时间:2012-10-03 23:03:21

标签: vb.net

我试图将VB源文件加载到内存中。但是,VB文件假定它与之关联的Project具有一些全局"导入的命名空间"在项目层面定义。此VB功能允许单个文件在每个文件中省略Imports语句(在C#中使用)。

    Dim sourceCode As String = ""
    'sourceCode &= "Imports System.Data" & vbNewLine
    sourceCode &= "Class Foo" & vbNewLine
    sourceCode &= "Sub Print()" & vbNewLine
    sourceCode &= "Dim dtbl As DataTable" & vbNewLine
    sourceCode &= "System.Console.WriteLine(""Hello, world!"")" & vbNewLine
    sourceCode &= "End Sub" & vbNewLine
    sourceCode &= "End Class" & vbNewLine

    Dim compiler As New Microsoft.VisualBasic.VBCodeProvider

    Dim params As New Compiler.CompilerParameters
    params.ReferencedAssemblies.Add("System.dll")
    params.ReferencedAssemblies.Add("System.Data.dll")
    params.ReferencedAssemblies.Add("System.Xml.dll")
    params.GenerateInMemory = True
    params.GenerateExecutable = False

    Dim results As Compiler.CompilerResults = compiler.CompileAssemblyFromSource(params, sourceCode)

    If results.Errors.Count > 0 Then
        For Each compileError In results.Errors
            Console.WriteLine(compileError.ToString)
        Next
        Return
    End If

    Dim assembly = results.CompiledAssembly

第2行被注释掉了。如果我取消注释并添加Imports语句,代码工作正常。如果我改变" Dim dtbl As DataTable"它也可以正常工作。 to" Dim dtbl As System.Data.DataTable"。

有没有一种方法可以将这个Imports语句提供给编译器或params,就好像它是一个全局项目级别的Imported Namespace?

而不是取消注释那行代码?

我可以将这个Imports语句添加到我读入的每个文件的顶部。但是如果它已经存在,那么我得到一个错误,Imports语句是重复的。我可以做一些正则表达式检查,看看Imports语句是否已经存在,但我想尽可能地利用System.CodeDom框架。

2 个答案:

答案 0 :(得分:1)

好的,没有答案:(我想框架不会做我想做的事。这是我使用Regex注入Imports语句的hacky解决方案。

sourceCode = AddImportsIfNeeded(sourceCode, "System.Data")


Private Function AddImportsIfNeeded(ByVal sourceCode As String, ByVal namespaceToImport As String) As String

    If Not Regex.IsMatch(sourceCode, "^\s*Imports\s+" & Regex.Escape(namespaceToImport) & "\s*$", RegexOptions.Multiline) Then
        Return "Imports " & namespaceToImport & vbNewLine & sourceCode
    End If
    Return sourceCode

End Function

请注意,如果文件包含Option语句(如Option Strict On),则不起作用。 Imports语句必须低于Option语句。

答案 1 :(得分:0)

您可以使用CompilerOptions类的CompilerParameters属性导入名称空间。将此行添加到您的示例中,编译器将不再生成编译器错误:

params.CompilerOptions = "/import:System.Data"