J
Joe Fallon
I have some complex logic which is fairly simply to build up into a string.
I needed a way to Eval this string and return a Boolean result.
This code works fine to achieve that goal.
My question is what happens to the dynamically created assembly when the
method is done running? Does GC take care of it?
Or is it stuck in RAM until the ASP.Net process is recycled?
This code executes pretty frequently (maybe 4 times per transaction) and I
am concerned that I could be eating up RAM and not releasing it in my
ASP.Net application.
I would hate to have code like this bring down the web server just because I
didn't clean it up correctly.
I took a quick look with Task Manager but when the code ran there was no new
process created. Is that because it is running inside the ASP.Net process?
I have seen a couple of posts that mention creating a separate appdomain to
handle this type of issue.
Is there some complete sample code somewhere that shows how to do this
without accidentally re-loading the dynamic assembly into the ASP.Net
process?
Thanks in advance for any help.
--
Joe Fallon
============================================================================
====
My web page calls the dynamic assembly code like this: where sbCode is the
complex Boolean logic in String format.
Dim objEval As New EvalProvider
Dim objResult As Object = objEval.Eval(sbCode.ToString)
============================================================================
====
Dynamic Assembly code:
============================================================================
====
Imports Microsoft.VisualBasic
Imports System
Imports System.Text
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.IO
Namespace myNamespace
''' <summary>
''' Think about this: Your application does a lot of business logic, some
of which requires complicated logical strings of code
''' that may change over time to meet certain business conditions or
metadata. Wouldn't it be great if you could pull the most
''' current string of code to be run out of your database based on certain
stored procedure input parameters, and be sure it's run
''' and you get back the desired result? In fact, the returned string of
code may even be dynamically created based on some of the
''' input parameters from the sproc itself.
''' </summary>
'''
''' <remarks>
''' http://www.eggheadcafe.com/articles/20030908.asp
''' </remarks>
Public Class EvalProvider
Public Function Eval(ByVal vbCode As String) As Object
Dim c As VBCodeProvider = New VBCodeProvider
Dim icc As ICodeCompiler = c.CreateCompiler()
Dim cp As CompilerParameters = New CompilerParameters
'Note: this list much match the list of Imports in the sb.Append
below!!
cp.ReferencedAssemblies.Add("system.dll")
cp.ReferencedAssemblies.Add("system.data.dll")
cp.ReferencedAssemblies.Add("system.xml.dll")
cp.CompilerOptions = "/t:library"
cp.GenerateInMemory = True
Dim sb As StringBuilder = New StringBuilder("")
sb.Append("Imports System" & vbCrLf)
sb.Append("Imports System.Data" & vbCrLf)
sb.Append("Imports System.Xml" & vbCrLf)
sb.Append("Namespace myNamespace " & vbCrLf)
sb.Append("Class myDynamicLib " & vbCrLf)
sb.Append("public function EvalCode() as Object " & vbCrLf)
sb.Append(vbCode & vbCrLf)
sb.Append("End Function " & vbCrLf)
sb.Append("End Class " & vbCrLf)
sb.Append("End Namespace" & vbCrLf)
'to debug your eval string uncomment this line
'Debug.WriteLine(sb.ToString())
Dim cr As CompilerResults = icc.CompileAssemblyFromSource(cp,
sb.ToString())
Dim a As System.Reflection.Assembly = cr.CompiledAssembly
Dim o As Object
Dim mi As MethodInfo
o = a.CreateInstance("myNamespace.myDynamicLib ")
Dim t As Type = o.GetType()
mi = t.GetMethod("EvalCode")
Dim s As Object
s = mi.Invoke(o, Nothing)
Return s
End Function
End Class
End Namespace
============================================================================
====
I needed a way to Eval this string and return a Boolean result.
This code works fine to achieve that goal.
My question is what happens to the dynamically created assembly when the
method is done running? Does GC take care of it?
Or is it stuck in RAM until the ASP.Net process is recycled?
This code executes pretty frequently (maybe 4 times per transaction) and I
am concerned that I could be eating up RAM and not releasing it in my
ASP.Net application.
I would hate to have code like this bring down the web server just because I
didn't clean it up correctly.
I took a quick look with Task Manager but when the code ran there was no new
process created. Is that because it is running inside the ASP.Net process?
I have seen a couple of posts that mention creating a separate appdomain to
handle this type of issue.
Is there some complete sample code somewhere that shows how to do this
without accidentally re-loading the dynamic assembly into the ASP.Net
process?
Thanks in advance for any help.
--
Joe Fallon
============================================================================
====
My web page calls the dynamic assembly code like this: where sbCode is the
complex Boolean logic in String format.
Dim objEval As New EvalProvider
Dim objResult As Object = objEval.Eval(sbCode.ToString)
============================================================================
====
Dynamic Assembly code:
============================================================================
====
Imports Microsoft.VisualBasic
Imports System
Imports System.Text
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.IO
Namespace myNamespace
''' <summary>
''' Think about this: Your application does a lot of business logic, some
of which requires complicated logical strings of code
''' that may change over time to meet certain business conditions or
metadata. Wouldn't it be great if you could pull the most
''' current string of code to be run out of your database based on certain
stored procedure input parameters, and be sure it's run
''' and you get back the desired result? In fact, the returned string of
code may even be dynamically created based on some of the
''' input parameters from the sproc itself.
''' </summary>
'''
''' <remarks>
''' http://www.eggheadcafe.com/articles/20030908.asp
''' </remarks>
Public Class EvalProvider
Public Function Eval(ByVal vbCode As String) As Object
Dim c As VBCodeProvider = New VBCodeProvider
Dim icc As ICodeCompiler = c.CreateCompiler()
Dim cp As CompilerParameters = New CompilerParameters
'Note: this list much match the list of Imports in the sb.Append
below!!
cp.ReferencedAssemblies.Add("system.dll")
cp.ReferencedAssemblies.Add("system.data.dll")
cp.ReferencedAssemblies.Add("system.xml.dll")
cp.CompilerOptions = "/t:library"
cp.GenerateInMemory = True
Dim sb As StringBuilder = New StringBuilder("")
sb.Append("Imports System" & vbCrLf)
sb.Append("Imports System.Data" & vbCrLf)
sb.Append("Imports System.Xml" & vbCrLf)
sb.Append("Namespace myNamespace " & vbCrLf)
sb.Append("Class myDynamicLib " & vbCrLf)
sb.Append("public function EvalCode() as Object " & vbCrLf)
sb.Append(vbCode & vbCrLf)
sb.Append("End Function " & vbCrLf)
sb.Append("End Class " & vbCrLf)
sb.Append("End Namespace" & vbCrLf)
'to debug your eval string uncomment this line
'Debug.WriteLine(sb.ToString())
Dim cr As CompilerResults = icc.CompileAssemblyFromSource(cp,
sb.ToString())
Dim a As System.Reflection.Assembly = cr.CompiledAssembly
Dim o As Object
Dim mi As MethodInfo
o = a.CreateInstance("myNamespace.myDynamicLib ")
Dim t As Type = o.GetType()
mi = t.GetMethod("EvalCode")
Dim s As Object
s = mi.Invoke(o, Nothing)
Return s
End Function
End Class
End Namespace
============================================================================
====