Как передать импортированные пространства имен в CompileAssemblyFromSource
Я пытаюсь загрузить исходный файл 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" на "Dim dtbl As System.Data.DataTable".
Вместо того, чтобы раскомментировать эту строку кода, есть ли способ передать этот оператор Imports в компилятор или параметры, как если бы это был глобальный проект Imported Namespace?
Я мог бы просто добавить этот оператор Imports в начало каждого файла, который я прочитал. Но если он уже есть, я получаю сообщение об ошибке, что оператор Imports дублируется. Я мог бы выполнить некоторую проверку Regex, чтобы увидеть, существует ли уже оператор Imports, но я бы хотел максимально использовать инфраструктуру System.CodeDom.
2 ответа
ОК, нет ответов:(Я думаю, что фреймворк не делает то, что я хотел бы сделать. Вот мое хакерское решение, использующее Regex для внедрения оператора Imports.
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). Операторы импорта должны быть ниже операторов выбора.
Вы можете импортировать пространства имен, используя CompilerOptions
собственность CompilerParameters
учебный класс. Добавьте эту строку в ваш пример, и компилятор больше не будет генерировать ошибку компилятора:
params.CompilerOptions = "/import:System.Data"