Using VBCodeProvider I am trying to compile and execute a block of VB code that performs a LINQ query and then processes the results. Two problems:
1. The code will not compile unless the anonymous types are declared as Object
2. After declaring as Object the methods are not found.
I have searched high and low for a solution but found nothing of any use.
Code to Compile (embedded in project as string resource)
---------------
Imports System.Linq
Imports System.Collections.Generic
Imports System
public Class Y
Friend Shared Function Result() as Integer
Dim gts As List(Of GtDef) = {New GtDef(1, "FirstGte"), New GtDef(2, "FirstGte")}.Cast(Of GtDef).ToList
Dim evts As List(Of EvDef) = {New EvDef(1, 1, "FirstEv"), New EvDef(2, 1, "SecondEv"), New EvDef(3, 2, "SecondEv")}.Cast(Of EvDef).ToList
Dim x = From g In gts Join e In evts On g.ID Equals e.ParentID Group e By key = e.ParentID Into Group Select GtGroup = key, EvGroup = Group
Dim sum As Integer = x.Count()
For Each gte In x
For Each evt In gte.EvGroup
sum += evt.ID
Next
Next
return sum
End Function
End Class
Public Class GtDef
Public ID As Integer
Public Name As String
Sub New(id As Integer, name As String)
Me.ID = id
Me.Name = name
End Sub
End Class
Public Class EvDef
Public ID As Integer
Public ParentID As Integer
Public Name As String
Sub New(id As Integer, parentID As Integer, name As String)
Me.ID = id
Me.ParentID = parentID
Me.Name = name
End Sub
End Class
Code used run compiler
----------------------
Dim compiler As Compiler.CodeDomProvider = Nothing
Dim provOptions As New Dictionary(Of String, String)
provOptions.Add("CompilerVersion", "v4.0")
compiler = New Microsoft.VisualBasic.VBCodeProvider(provOptions)
Dim compilerParams As New Compiler.CompilerParameters()
Dim assems As String() = AppDomain.CurrentDomain.GetAssemblies().Where(Function(find) Not find.IsDynamic).Select(Function(find) find.Location).ToArray
compilerParams.ReferencedAssemblies.AddRange(assems)
Dim compResults As Compiler.CompilerResults = compiler.CompileAssemblyFromSource(compilerParams, {My.Resources.Code})
Dim cls As Type = compResults.CompiledAssembly.GetType("Y")
cls.InvokeMember("Result", System.Reflection.BindingFlags.InvokeMethod Or System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Static, Nothing, Nothing, Nothing)
1. The code will not compile unless the anonymous types are declared as Object
2. After declaring as Object the methods are not found.
I have searched high and low for a solution but found nothing of any use.
Code to Compile (embedded in project as string resource)
---------------
Imports System.Linq
Imports System.Collections.Generic
Imports System
public Class Y
Friend Shared Function Result() as Integer
Dim gts As List(Of GtDef) = {New GtDef(1, "FirstGte"), New GtDef(2, "FirstGte")}.Cast(Of GtDef).ToList
Dim evts As List(Of EvDef) = {New EvDef(1, 1, "FirstEv"), New EvDef(2, 1, "SecondEv"), New EvDef(3, 2, "SecondEv")}.Cast(Of EvDef).ToList
Dim x = From g In gts Join e In evts On g.ID Equals e.ParentID Group e By key = e.ParentID Into Group Select GtGroup = key, EvGroup = Group
Dim sum As Integer = x.Count()
For Each gte In x
For Each evt In gte.EvGroup
sum += evt.ID
Next
Next
return sum
End Function
End Class
Public Class GtDef
Public ID As Integer
Public Name As String
Sub New(id As Integer, name As String)
Me.ID = id
Me.Name = name
End Sub
End Class
Public Class EvDef
Public ID As Integer
Public ParentID As Integer
Public Name As String
Sub New(id As Integer, parentID As Integer, name As String)
Me.ID = id
Me.ParentID = parentID
Me.Name = name
End Sub
End Class
Code used run compiler
----------------------
Dim compiler As Compiler.CodeDomProvider = Nothing
Dim provOptions As New Dictionary(Of String, String)
provOptions.Add("CompilerVersion", "v4.0")
compiler = New Microsoft.VisualBasic.VBCodeProvider(provOptions)
Dim compilerParams As New Compiler.CompilerParameters()
Dim assems As String() = AppDomain.CurrentDomain.GetAssemblies().Where(Function(find) Not find.IsDynamic).Select(Function(find) find.Location).ToArray
compilerParams.ReferencedAssemblies.AddRange(assems)
Dim compResults As Compiler.CompilerResults = compiler.CompileAssemblyFromSource(compilerParams, {My.Resources.Code})
Dim cls As Type = compResults.CompiledAssembly.GetType("Y")
cls.InvokeMember("Result", System.Reflection.BindingFlags.InvokeMethod Or System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Static, Nothing, Nothing, Nothing)