Dynamische Codegenerierung mit VB.NET

Veröffentlicht: 18. Feb 2003 | Aktualisiert: 23. Jun 2004
Von Mathias Schiffer

Das .NET Framework ermöglicht es, mit wenigen Codezeilen einen eigenen "Scripting Host" zu schreiben und Anwendungen auf einfache Weise mit Scriptingfunktionalität à la VBA zu versehen.

Die notwendigen Bordmittel hierfür sind bereits vorhanden und spezielle Scriptsprachen sind nicht mehr zwingend notwendig.

Der nachfolgende Code zeigt, wie einfach es geht. Und wer es noch eleganter mag, kann gar die Funktion CreateAssemblyFromFile so erweitern, dass der jeweils passende Compiler z.B. anhand der Dateiendung ermittelt und zurückgegeben wird.

' Konsolenanwendung "Scripting" 
Imports System 
Imports System.CodeDom 
Imports System.CodeDom.Compiler 
Imports System.Reflection 
Module Module1 
  Public Function CreateAssemblyFromCode( _ 

  ByVal Code As String _ 
  ) As [Assembly] 

 ' Assembly aus VB.NET-Sourcecode in einem String erzeugen: 
 ' CodeDomProvider für VB.NET erzeugen 
 Dim CDP As CodeDomProvider _ 
   = New Microsoft.VisualBasic.VBCodeProvider() 
 ' Compiler erzeugen 
 Dim Compiler As ICodeCompiler _ 
  = CDP.CreateCompiler() 
 ' Compiler-Parameter erzeugen 
 Dim CP As New CompilerParameters() 
 CP.GenerateInMemory = True 
 ' Compilieren und Compiler-Ergebnis ermitteln 
 Dim CR As CompilerResults _ 
  = Compiler.CompileAssemblyFromSource(CP, Code) 
 ' Im Fehlerfall Nothing zurückgeben 
 If CR.Errors.Count <> 0 Then 
   Return Nothing 
 Else 
   Return CR.CompiledAssembly 
 End If 
  End Function 
  Public Function CreateAssemblyFromFile( _ 
  ByVal Filename As String _ 
  ) As [Assembly] 
 ' Assembly aus VB.NET-Sourcecode in einer Datei erzeugen: 
 ' CodeDomProvider für VB.NET erzeugen 
 Dim CDP As CodeDomProvider _ 
   = New Microsoft.VisualBasic.VBCodeProvider() 
 ' Compiler erzeugen 
 Dim Compiler As ICodeCompiler _ 
  = CDP.CreateCompiler() 
 ' Compiler-Parameter erzeugen 
 Dim CP As New CompilerParameters() 
 CP.GenerateInMemory = True 
 ' Compilieren und Compiler-Ergebnis ermitteln 
 Dim CR As CompilerResults _ 
  = Compiler.CompileAssemblyFromFile(CP, Filename) 
 ' Im Fehlerfall Nothing zurückgeben 
 If CR.Errors.Count <> 0 Then 
   Return Nothing 
 Else 
   Return CR.CompiledAssembly 
 End If 
  End Function 
  ' Das testende Hauptprogramm 
  Sub Main() 
 ' Auszuführender Beispielcode in einem String 
 Dim Code As String = _ 
  "Namespace aixsoft" & vbNewLine & _ 
 "Public Class Math" & vbNewLine & _ 
   "Public Function Add(ByVal x as Integer, " & _ 
   "ByVal y as Integer)" & vbNewLine & _ 
  "Return x+y" & vbNewLine & _ 
   "End Function" & vbNewLine & _ 
 "End Class" & vbNewLine & _ 
  "End Namespace" 
 ' Assembly aus dem Code erzeugen 
 Dim ASM As [Assembly] _ 
   = CreateAssemblyFromCode(Code) 
 ' ... und ein Test der Assembly: 
 Dim O As Object _ 
 = ASM.CreateInstance("aixsoft.Math") 
 Dim T As Type _ 
 = O.GetType() 
 Dim MI As MethodInfo _ 
  = T.GetMethod("Add") 
 ' Parameterwerte festlegen 
 Dim Param(1) As Object 
 Param(0) = 17 
 Param(1) = 25 
 ' Add-Funktion aufrufen 
 Dim Result As Object _ 
   = MI.Invoke(O, Param) 
 ' Ausgabe des Ergebnisses 
 Console.WriteLine("17 + 25 = " & Result.ToString) 
  End Sub 
End Module

Anzeigen: