Connecting Tech Pros Worldwide Help | Site Map

Eval code and AppDomains

Joe Fallon
Guest
 
Posts: n/a
#1: Nov 19 '05
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
================================================== ==========================
====





Scott Allen
Guest
 
Posts: n/a
#2: Nov 19 '05

re: Eval code and AppDomains


Hi Joe:

Once an assembly is loaded it can't be removed, unfortunately the GC can't
help there.
The code runs inside the same process as you asp.net app so you won't see
a new process appear.

The only true way to get rid of the assembly and reclaim memory is to use
a new appdomain as you pointed out.
There is good article here: http://www.west-wind.com/presentatio...ynamicCode.htm

I'd also have some concern with performance if you need to scale this up
to a large number of users. Crossing app domains and generating these assemblies
can chew up CPU and memory if you need to do this 4 times per request.

--
Scott
http://www.OdeToCode.com/blogs/scott/
[color=blue]
> 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.
>
> ================================================== ====================
> ======
> ====
> 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
> ================================================== ====================
> ====== ====
>[/color]


Cor Ligthert
Guest
 
Posts: n/a
#3: Nov 19 '05

re: Eval code and AppDomains


Joe,

Without looking to deep or trying, would I set the class you use in a
component.

Cor


Joe Fallon
Guest
 
Posts: n/a
#4: Nov 19 '05

re: Eval code and AppDomains


Scott,
That was 4 times per transaction which is a single page in a large site. It
is not every hit.

I think I have seen that article - I will read it closely. I use Rick's
stuff in other areas.

Do you know of any other way to Eval a String to get a Boolean result other
than dynamically generating the assembly as shown below?

Do you know if Eval will be a built-in function in ver 2.0 of the .Net
framework?

Thanks.
--
Joe Fallon



"Scott Allen" <scott@nospam.OdeToCode.com> wrote in message
news:59960632422914913133552@msnews.microsoft.com. ..[color=blue]
> Hi Joe:
>
> Once an assembly is loaded it can't be removed, unfortunately the GC can't
> help there.
> The code runs inside the same process as you asp.net app so you won't see
> a new process appear.
>
> The only true way to get rid of the assembly and reclaim memory is to use
> a new appdomain as you pointed out.
> There is good article here:[/color]
http://www.west-wind.com/presentatio...ynamicCode.htm[color=blue]
>
> I'd also have some concern with performance if you need to scale this up
> to a large number of users. Crossing app domains and generating these[/color]
assemblies[color=blue]
> can chew up CPU and memory if you need to do this 4 times per request.
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>[color=green]
> > 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.
> >
> > ================================================== ====================
> > ======
> > ====
> > 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
> > ================================================== ====================
> > ====== ====
> >[/color]
>
>[/color]


Jay B. Harlow [MVP - Outlook]
Guest
 
Posts: n/a
#5: Nov 19 '05

re: Eval code and AppDomains


Joe,[color=blue]
> 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.[/color]
Concern! Are you creating a dynamic assembly 4 times per transaction? Isn't
that in itself causing a performance issue?

I would consider keeping a Hashtable matching code snippets (the vbCode
parameter) to the compiled Assembly. I would only create the compiled
assembly if it was not previous registered in my Hashtable. The caveat is
you would need to ensure the code is thread safe...

My other concern is if you compile the same snippet 4 times you actually
wind up with 4 "identical" yet individual compiled assemblies...
[color=blue]
> My question is what happens to the dynamically created assembly when the
> method is done running?[/color]
I would expect the assembly to remain in the current AppDomain until that
AppDomain is unloaded, You might be able to handle the
AppDomain.AssemblyLoad & AppDomain.DomainUnload events to monitor its
lifetime.

Notice there is no AppDomain.AssemblyUnload event, as you cannot unload
assemblies from an AppDomain without unloading the entire AppDomain.
[color=blue]
> Or is it stuck in RAM until the ASP.Net process is recycled?[/color]
Based on how other assemblies work with an AppDomain that is correct.

[color=blue]
> 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?[/color]
I don't have a specific link to a complete sample, however you should be
able to create a "EvalProvider" AppDomain, load & instantiate "EvalProvider"
class & assembly in this second AppDomain, when you call EvalProvider.Eval
it should run in this second AppDomain.

The following might get you started:

http://msdn.microsoft.com/library/de...rp05162002.asp

Its C#, however it should be easily converted to VB.NET, post if you need
help.

One last item: The other major advantage of running the snippets
(EvalProvider.Eval) in its own AddDomain is that you can "lock down"
(security wise/permission wise) that AppDomain so that the snippet cannot do
stuff its not suppose to. Depending on who is writing the snippets this can
be a good thing :-)

Hope this helps
Jay


"Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
news:%23Pmni7yAFHA.824@TK2MSFTNGP11.phx.gbl...[color=blue]
>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
> ================================================== ==========================
> ====
>
>
>
>
>[/color]


Joe Fallon
Guest
 
Posts: n/a
#6: Nov 19 '05

re: Eval code and AppDomains


Jay,
Thanks for your input. You have helped me a lot in the past. I really
appreciate it.

0. BTW this dynamic assembly code only runs on a single page in a large web
site when a user enters a complex transaction. So I am not overly concerned
about it scaling (yet) since this will be a small percentage of the total
hits on the site.

1. Do you know of any other way to Eval a String to get a Boolean result
other
than dynamically generating the assembly as shown below?

e.g. If I have a string such as "1=1" and I try to Cbool it I will get an
error.
Cbool("1=1") - error!

But Cbool(1=1) will return True. (Note that this is not a string!)

So the all the dynamic assembly does is execute my string and return T/F.

This is the core of the dynamic code which is executed:
Dim boolResult As Boolean = Cbool((1=1))
Return boolResult
Notice how my original string is now represented as something that will
evaluate correctly.

So, if there is some other way to get the same result I would like to know
about it.

FYI - I have some complex rules that become simple to code as a long Boolean
string which when evaluated returns T/F which is the only result I really
need. When I tried coding these complex rules without building up a string
it quickly got unmanageable. There was a huge advantage to building a string
in the code. But now Evaling the string with a dynamic asembly seems to be
an issue.

2. Do you know if Eval will be a built-in function in ver 2.0 of the .Net
framework?

3. Good point about the Hashtable. If it stored both the string and the
result then it could act as a cache and dramatically reduce the dynamic
assembly creation by simply retrieving the result for each matching string
that has been previously computed. I think there would be a large number of
matches since the rules would not change that frequently and so the strings
would tend to be repeated for each transaction type.

4. The hashtable resolves the point about compiling the same snippet 4 times
and creating 4 identical asemblies.
The original idea was to create the dynamic assembly and just "throw it
away" when it Eval(uated) the snippet.
But as I read more about it I learned you can't unload an assembly and so I
became concerned that I would be needlessly wasting memory. As I understand
it, ASP.Net monitors its AppDomain for "memory pressure" among other things
and will tear it down and build a new one automatically. I guess my dynamic
asemblies would just cause it to do this more frequently. Agree?

5. Rick Strahl's article showed how to create a separate appdomain. I
downloaded his code and got it working within the current appdomain but it
failed when trying to create a new one. Interestingly, he was working on the
exact same issue today and had MS Support on the line for 2 hours until the
figured out the problem. Sounds like the same problem I was having with his
code so I am hoping I can get it working tomorrow. This is a very tricky
issue. Lots of people talk about it but Rick was the only one who tried to
abstract the problem and create a class that shows how to do it. MS should
do this since they are the ones who know what works and what doesn't. The
documentation is a bit sketchy and without MS Support help Rick wouldn't
have solved it either since there were no errors returned from the code.

6. Good point on the security of a separate AppDomain.

7. I was considering setting a variable (count of hashtable?) that would
count the number of times I dynamically executed a snippet. When it exceeded
a certain threshhold I planned to tear down the separate AppDomain and start
over. Agree?

8. Since I am running in ASP.Net I would like to use the Cache to store the
hashtable. But the problem is the dynamic eval code is not in my code behind
pages. It is in my Business Object tier and that does not know anything
about the ASP.Net Cache. Any recommendations on how to store this hashtable
in my BO tier so that I will always have access to it?

Thanks!
--
Joe Fallon



"Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@msn.com> wrote in message
news:%23pGE9q7AFHA.3616@TK2MSFTNGP11.phx.gbl...[color=blue]
> Joe,[color=green]
>> 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.[/color]
> Concern! Are you creating a dynamic assembly 4 times per transaction?
> Isn't that in itself causing a performance issue?
>
> I would consider keeping a Hashtable matching code snippets (the vbCode
> parameter) to the compiled Assembly. I would only create the compiled
> assembly if it was not previous registered in my Hashtable. The caveat is
> you would need to ensure the code is thread safe...
>
> My other concern is if you compile the same snippet 4 times you actually
> wind up with 4 "identical" yet individual compiled assemblies...
>[color=green]
>> My question is what happens to the dynamically created assembly when the
>> method is done running?[/color]
> I would expect the assembly to remain in the current AppDomain until that
> AppDomain is unloaded, You might be able to handle the
> AppDomain.AssemblyLoad & AppDomain.DomainUnload events to monitor its
> lifetime.
>
> Notice there is no AppDomain.AssemblyUnload event, as you cannot unload
> assemblies from an AppDomain without unloading the entire AppDomain.
>[color=green]
>> Or is it stuck in RAM until the ASP.Net process is recycled?[/color]
> Based on how other assemblies work with an AppDomain that is correct.
>
>[color=green]
>> 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?[/color]
> I don't have a specific link to a complete sample, however you should be
> able to create a "EvalProvider" AppDomain, load & instantiate
> "EvalProvider" class & assembly in this second AppDomain, when you call
> EvalProvider.Eval it should run in this second AppDomain.
>
> The following might get you started:
>
> http://msdn.microsoft.com/library/de...rp05162002.asp
>
> Its C#, however it should be easily converted to VB.NET, post if you need
> help.
>
> One last item: The other major advantage of running the snippets
> (EvalProvider.Eval) in its own AddDomain is that you can "lock down"
> (security wise/permission wise) that AppDomain so that the snippet cannot
> do stuff its not suppose to. Depending on who is writing the snippets this
> can be a good thing :-)
>
> Hope this helps
> Jay
>
>
> "Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
> news:%23Pmni7yAFHA.824@TK2MSFTNGP11.phx.gbl...[color=green]
>>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
>> ================================================== ==========================
>> ====
>>
>>
>>
>>
>>[/color]
>
>[/color]


Scott Allen
Guest
 
Posts: n/a
#7: Nov 19 '05

re: Eval code and AppDomains


Hi Joe, if you want to eval things like "1=1" or "6+4 > 3" then I
suggest using the Eval method in the JScript.NET libraries.

i.e:

Microsoft.JScript.Vsa.VsaEngine jEngine =
Microsoft.JScript.Vsa.VsaEngine.CreateEngine();

return Microsoft.JScript.Eval.JScriptEvaluate("1=1", jEngine);

I have another example here, where the eval code is made into a
dynamic assembly and cached:
http://www.odetocode.com/Code/80.aspx

HTH,

--
Scott
http://www.OdeToCode.com/blogs/scott/

On Wed, 26 Jan 2005 09:38:59 -0500, "Joe Fallon"
<jfallon1@nospamtwcny.rr.com> wrote:
[color=blue]
>Scott,
>That was 4 times per transaction which is a single page in a large site. It
>is not every hit.
>
>I think I have seen that article - I will read it closely. I use Rick's
>stuff in other areas.
>
>Do you know of any other way to Eval a String to get a Boolean result other
>than dynamically generating the assembly as shown below?
>
>Do you know if Eval will be a built-in function in ver 2.0 of the .Net
>framework?
>
>Thanks.[/color]

Joe Fallon
Guest
 
Posts: n/a
#8: Nov 19 '05

re: Eval code and AppDomains


Scott,
Very interesting!
I will take a close look at it.
Thanks!
--
Joe Fallon
Access MVP


"Scott Allen" <scott@nospam.odetocode.com> wrote in message
news:cfrgv05qj5kbakjkp2mk4m012inerd069f@4ax.com...[color=blue]
> Hi Joe, if you want to eval things like "1=1" or "6+4 > 3" then I
> suggest using the Eval method in the JScript.NET libraries.
>
> i.e:
>
> Microsoft.JScript.Vsa.VsaEngine jEngine =
> Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
>
> return Microsoft.JScript.Eval.JScriptEvaluate("1=1", jEngine);
>
> I have another example here, where the eval code is made into a
> dynamic assembly and cached:
> http://www.odetocode.com/Code/80.aspx
>
> HTH,
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>
> On Wed, 26 Jan 2005 09:38:59 -0500, "Joe Fallon"
> <jfallon1@nospamtwcny.rr.com> wrote:
>[color=green]
> >Scott,
> >That was 4 times per transaction which is a single page in a large site.[/color][/color]
It[color=blue][color=green]
> >is not every hit.
> >
> >I think I have seen that article - I will read it closely. I use Rick's
> >stuff in other areas.
> >
> >Do you know of any other way to Eval a String to get a Boolean result[/color][/color]
other[color=blue][color=green]
> >than dynamically generating the assembly as shown below?
> >
> >Do you know if Eval will be a built-in function in ver 2.0 of the .Net
> >framework?
> >
> >Thanks.[/color]
>[/color]


Joe Fallon
Guest
 
Posts: n/a
#9: Nov 19 '05

re: Eval code and AppDomains


Scott,
I added references to Microsoft.Jscript and Microsoft.VSA to my project and
then
I tried this simple example which failed with an Illegal assignment error.

Any ideas?

Dim x As Object = CObj("1=1")

Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
Microsoft.JScript.Vsa.VsaEngine.CreateEngine()

Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x, jEngine)


--- Stack Trace ---
eval code: Line 1 - Error: Illegal assignment



--
Joe Fallon



"Scott Allen" <scott@nospam.odetocode.com> wrote in message
news:cfrgv05qj5kbakjkp2mk4m012inerd069f@4ax.com...[color=blue]
> Hi Joe, if you want to eval things like "1=1" or "6+4 > 3" then I
> suggest using the Eval method in the JScript.NET libraries.
>
> i.e:
>
> Microsoft.JScript.Vsa.VsaEngine jEngine =
> Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
>
> return Microsoft.JScript.Eval.JScriptEvaluate("1=1", jEngine);
>
> I have another example here, where the eval code is made into a
> dynamic assembly and cached:
> http://www.odetocode.com/Code/80.aspx
>
> HTH,
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>
> On Wed, 26 Jan 2005 09:38:59 -0500, "Joe Fallon"
> <jfallon1@nospamtwcny.rr.com> wrote:
>[color=green]
> >Scott,
> >That was 4 times per transaction which is a single page in a large site.[/color][/color]
It[color=blue][color=green]
> >is not every hit.
> >
> >I think I have seen that article - I will read it closely. I use Rick's
> >stuff in other areas.
> >
> >Do you know of any other way to Eval a String to get a Boolean result[/color][/color]
other[color=blue][color=green]
> >than dynamically generating the assembly as shown below?
> >
> >Do you know if Eval will be a built-in function in ver 2.0 of the .Net
> >framework?
> >
> >Thanks.[/color]
>[/color]


Joe Fallon
Guest
 
Posts: n/a
#10: Nov 19 '05

re: Eval code and AppDomains


Dim x As Object = CObj("1==1")

Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
Microsoft.JScript.Vsa.VsaEngine.CreateEngine()

Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x, jEngine)

This worked and gave a result of True.

I guess jscript uses a double equal sign for equal and a single equal sign
to assign a value.

Being a VB coder I was not aware of this.

I learned something new today.

This looks quite useful.I will probably try to implement it now that my
quick tests show it works.

Thanks!


--
Joe Fallon



"Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
news:#dBz4ZIBFHA.1564@TK2MSFTNGP09.phx.gbl...[color=blue]
> Scott,
> I added references to Microsoft.Jscript and Microsoft.VSA to my project[/color]
and[color=blue]
> then
> I tried this simple example which failed with an Illegal assignment error.
>
> Any ideas?
>
> Dim x As Object = CObj("1=1")
>
> Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
> Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
>
> Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x,[/color]
jEngine)[color=blue]
>
>
> --- Stack Trace ---
> eval code: Line 1 - Error: Illegal assignment
>
>
>
> --
> Joe Fallon
>
>
>
> "Scott Allen" <scott@nospam.odetocode.com> wrote in message
> news:cfrgv05qj5kbakjkp2mk4m012inerd069f@4ax.com...[color=green]
> > Hi Joe, if you want to eval things like "1=1" or "6+4 > 3" then I
> > suggest using the Eval method in the JScript.NET libraries.
> >
> > i.e:
> >
> > Microsoft.JScript.Vsa.VsaEngine jEngine =
> > Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
> >
> > return Microsoft.JScript.Eval.JScriptEvaluate("1=1", jEngine);
> >
> > I have another example here, where the eval code is made into a
> > dynamic assembly and cached:
> > http://www.odetocode.com/Code/80.aspx
> >
> > HTH,
> >
> > --
> > Scott
> > http://www.OdeToCode.com/blogs/scott/
> >
> > On Wed, 26 Jan 2005 09:38:59 -0500, "Joe Fallon"
> > <jfallon1@nospamtwcny.rr.com> wrote:
> >[color=darkred]
> > >Scott,
> > >That was 4 times per transaction which is a single page in a large[/color][/color][/color]
site.[color=blue]
> It[color=green][color=darkred]
> > >is not every hit.
> > >
> > >I think I have seen that article - I will read it closely. I use Rick's
> > >stuff in other areas.
> > >
> > >Do you know of any other way to Eval a String to get a Boolean result[/color][/color]
> other[color=green][color=darkred]
> > >than dynamically generating the assembly as shown below?
> > >
> > >Do you know if Eval will be a built-in function in ver 2.0 of the .Net
> > >framework?
> > >
> > >Thanks.[/color]
> >[/color]
>
>[/color]


Scott Allen
Guest
 
Posts: n/a
#11: Nov 19 '05

re: Eval code and AppDomains


Yes, the tricky part now is writing the JScript correctly to be
evaluated :)

--
Scott
http://www.OdeToCode.com/blogs/scott/

On Thu, 27 Jan 2005 10:50:04 -0500, "Joe Fallon"
<jfallon1@nospamtwcny.rr.com> wrote:
[color=blue]
>Dim x As Object = CObj("1==1")
>
>Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
>Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
>
>Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x, jEngine)
>
>This worked and gave a result of True.
>
>I guess jscript uses a double equal sign for equal and a single equal sign
>to assign a value.
>
>Being a VB coder I was not aware of this.
>
>I learned something new today.
>
>This looks quite useful.I will probably try to implement it now that my
>quick tests show it works.
>
>Thanks![/color]

Joe Fallon
Guest
 
Posts: n/a
#12: Nov 19 '05

re: Eval code and AppDomains


Scott,
Thanks!
This was exactly what I was looking for.

I was able to implement it successfully. It does exactly what I need it to
do.
Now I don't have to worry about separate AppDomains and dynamically creating
an assembly multiple times.

I simply added 2 references to my Class Library project.
1. Microsoft.JScript
2. Microsoft.VSA

Then I added these 2 lines of code:

Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
Dim objResult As Object =
Microsoft.JScript.Eval.JScriptEvaluate(sbCode.ToSt ring, jEngine)
If CBool(objResult) = True Then
...

sbCode is the Stringbuilder that builds up the complex expressions.

================================================== ==================

On a side note:
I read you article but I think I am missing something.
What is wrong with the technique I am using above?
Why did you talk about deploying assemblies and then come up with a dynamic
assembly (which at least is only created once)?
Doesn't the dynamic assembly require the same references as I added?

I would appreciate it if you could clarify this as I would like to "put this
to bed".
--
Joe Fallon



"Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
news:uughffIBFHA.3708@TK2MSFTNGP14.phx.gbl...[color=blue]
> Dim x As Object = CObj("1==1")
>
> Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
> Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
>
> Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x,[/color]
jEngine)[color=blue]
>
> This worked and gave a result of True.
>
> I guess jscript uses a double equal sign for equal and a single equal sign
> to assign a value.
>
> Being a VB coder I was not aware of this.
>
> I learned something new today.
>
> This looks quite useful.I will probably try to implement it now that my
> quick tests show it works.
>
> Thanks!
>
>
> --
> Joe Fallon
>
>
>
> "Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
> news:#dBz4ZIBFHA.1564@TK2MSFTNGP09.phx.gbl...[color=green]
> > Scott,
> > I added references to Microsoft.Jscript and Microsoft.VSA to my project[/color]
> and[color=green]
> > then
> > I tried this simple example which failed with an Illegal assignment[/color][/color]
error.[color=blue][color=green]
> >
> > Any ideas?
> >
> > Dim x As Object = CObj("1=1")
> >
> > Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
> > Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
> >
> > Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x,[/color]
> jEngine)[color=green]
> >
> >
> > --- Stack Trace ---
> > eval code: Line 1 - Error: Illegal assignment
> >
> >
> >
> > --
> > Joe Fallon
> >
> >
> >
> > "Scott Allen" <scott@nospam.odetocode.com> wrote in message
> > news:cfrgv05qj5kbakjkp2mk4m012inerd069f@4ax.com...[color=darkred]
> > > Hi Joe, if you want to eval things like "1=1" or "6+4 > 3" then I
> > > suggest using the Eval method in the JScript.NET libraries.
> > >
> > > i.e:
> > >
> > > Microsoft.JScript.Vsa.VsaEngine jEngine =
> > > Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
> > >
> > > return Microsoft.JScript.Eval.JScriptEvaluate("1=1", jEngine);
> > >
> > > I have another example here, where the eval code is made into a
> > > dynamic assembly and cached:
> > > http://www.odetocode.com/Code/80.aspx
> > >
> > > HTH,
> > >
> > > --
> > > Scott
> > > http://www.OdeToCode.com/blogs/scott/
> > >
> > > On Wed, 26 Jan 2005 09:38:59 -0500, "Joe Fallon"
> > > <jfallon1@nospamtwcny.rr.com> wrote:
> > >
> > > >Scott,
> > > >That was 4 times per transaction which is a single page in a large[/color][/color]
> site.[color=green]
> > It[color=darkred]
> > > >is not every hit.
> > > >
> > > >I think I have seen that article - I will read it closely. I use[/color][/color][/color]
Rick's[color=blue][color=green][color=darkred]
> > > >stuff in other areas.
> > > >
> > > >Do you know of any other way to Eval a String to get a Boolean result[/color]
> > other[color=darkred]
> > > >than dynamically generating the assembly as shown below?
> > > >
> > > >Do you know if Eval will be a built-in function in ver 2.0 of the[/color][/color][/color]
..Net[color=blue][color=green][color=darkred]
> > > >framework?
> > > >
> > > >Thanks.
> > >[/color]
> >
> >[/color]
>
>[/color]


Joe Fallon
Guest
 
Posts: n/a
#13: Nov 19 '05

re: Eval code and AppDomains


LOL.

A quick jscript tutorial showed me what the various operators are so the
code changes from VB to Jscript were real simple.

= is ==
<> is !=
OR is ||
AND is &&

Could you take a look at my other post and answer my questions about your
article?
Thanks.

--
Joe Fallon


"Scott Allen" <scott@nospam.odetocode.com> wrote in message
news:i5aiv018d56la8iroo3fv62e0qmmjmr1au@4ax.com...[color=blue]
> Yes, the tricky part now is writing the JScript correctly to be
> evaluated :)
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>
> On Thu, 27 Jan 2005 10:50:04 -0500, "Joe Fallon"
> <jfallon1@nospamtwcny.rr.com> wrote:
>[color=green]
> >Dim x As Object = CObj("1==1")
> >
> >Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
> >Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
> >
> >Dim objResult As Object = Microsoft.JScript.Eval.JScriptEvaluate(x,[/color][/color]
jEngine)[color=blue][color=green]
> >
> >This worked and gave a result of True.
> >
> >I guess jscript uses a double equal sign for equal and a single equal[/color][/color]
sign[color=blue][color=green]
> >to assign a value.
> >
> >Being a VB coder I was not aware of this.
> >
> >I learned something new today.
> >
> >This looks quite useful.I will probably try to implement it now that my
> >quick tests show it works.
> >
> >Thanks![/color]
>[/color]


Jay B. Harlow [MVP - Outlook]
Guest
 
Posts: n/a
#14: Nov 19 '05

re: Eval code and AppDomains


Joe,[color=blue]
> 1. Do you know of any other way to Eval a String to get a Boolean result[/color]
JavaScript as Scott shows in the microsoft.public.dotnet.framework.aspnet
newsgroup (not sure how this (languages.vb) newsgroup got left off that half
of this thread).

Alternatively you could use a computed column in a DataTable, if your data
is not already in a DataTable this may not work very well... The Expresssion
syntax in the DataSet OM is closer to VB, then JavaScripts, however with
limits.

http://msdn.microsoft.com/library/de...ssiontopic.asp
[color=blue]
> 2. Do you know if Eval will be a built-in function in ver 2.0 of the .Net
> framework?[/color]
Not that I know of
[color=blue]
> 8. Since I am running in ASP.Net I would like to use the Cache to store
> the[/color]
I have not looked at it a lot, there is the Caching Application Block
http://msdn.microsoft.com/library/de...chingblock.asp.

I normally simply keep the values in a Shared variables, however there is no
getting ride of old one...

Hope this helps
Jay

"Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
news:eOBOiBBBFHA.2584@TK2MSFTNGP09.phx.gbl...[color=blue]
> Jay,
> Thanks for your input. You have helped me a lot in the past. I really
> appreciate it.
>
> 0. BTW this dynamic assembly code only runs on a single page in a large
> web site when a user enters a complex transaction. So I am not overly
> concerned about it scaling (yet) since this will be a small percentage of
> the total hits on the site.
>
> 1. Do you know of any other way to Eval a String to get a Boolean result
> other
> than dynamically generating the assembly as shown below?
>
> e.g. If I have a string such as "1=1" and I try to Cbool it I will get an
> error.
> Cbool("1=1") - error!
>
> But Cbool(1=1) will return True. (Note that this is not a string!)
>
> So the all the dynamic assembly does is execute my string and return T/F.
>
> This is the core of the dynamic code which is executed:
> Dim boolResult As Boolean = Cbool((1=1))
> Return boolResult
> Notice how my original string is now represented as something that will
> evaluate correctly.
>
> So, if there is some other way to get the same result I would like to know
> about it.
>
> FYI - I have some complex rules that become simple to code as a long
> Boolean string which when evaluated returns T/F which is the only result I
> really need. When I tried coding these complex rules without building up a
> string it quickly got unmanageable. There was a huge advantage to building
> a string in the code. But now Evaling the string with a dynamic asembly
> seems to be an issue.
>
> 2. Do you know if Eval will be a built-in function in ver 2.0 of the .Net
> framework?
>
> 3. Good point about the Hashtable. If it stored both the string and the
> result then it could act as a cache and dramatically reduce the dynamic
> assembly creation by simply retrieving the result for each matching string
> that has been previously computed. I think there would be a large number
> of matches since the rules would not change that frequently and so the
> strings would tend to be repeated for each transaction type.
>
> 4. The hashtable resolves the point about compiling the same snippet 4
> times and creating 4 identical asemblies.
> The original idea was to create the dynamic assembly and just "throw it
> away" when it Eval(uated) the snippet.
> But as I read more about it I learned you can't unload an assembly and so
> I became concerned that I would be needlessly wasting memory. As I
> understand it, ASP.Net monitors its AppDomain for "memory pressure" among
> other things and will tear it down and build a new one automatically. I
> guess my dynamic asemblies would just cause it to do this more frequently.
> Agree?
>
> 5. Rick Strahl's article showed how to create a separate appdomain. I
> downloaded his code and got it working within the current appdomain but it
> failed when trying to create a new one. Interestingly, he was working on
> the exact same issue today and had MS Support on the line for 2 hours
> until the figured out the problem. Sounds like the same problem I was
> having with his code so I am hoping I can get it working tomorrow. This is
> a very tricky issue. Lots of people talk about it but Rick was the only
> one who tried to abstract the problem and create a class that shows how to
> do it. MS should do this since they are the ones who know what works and
> what doesn't. The documentation is a bit sketchy and without MS Support
> help Rick wouldn't have solved it either since there were no errors
> returned from the code.
>
> 6. Good point on the security of a separate AppDomain.
>
> 7. I was considering setting a variable (count of hashtable?) that would
> count the number of times I dynamically executed a snippet. When it
> exceeded a certain threshhold I planned to tear down the separate
> AppDomain and start over. Agree?
>
> 8. Since I am running in ASP.Net I would like to use the Cache to store
> the hashtable. But the problem is the dynamic eval code is not in my code
> behind pages. It is in my Business Object tier and that does not know
> anything about the ASP.Net Cache. Any recommendations on how to store this
> hashtable in my BO tier so that I will always have access to it?
>
> Thanks!
> --
> Joe Fallon
>
>
>
> "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@msn.com> wrote in message
> news:%23pGE9q7AFHA.3616@TK2MSFTNGP11.phx.gbl...[color=green]
>> Joe,[color=darkred]
>>> 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.[/color]
>> Concern! Are you creating a dynamic assembly 4 times per transaction?
>> Isn't that in itself causing a performance issue?
>>
>> I would consider keeping a Hashtable matching code snippets (the vbCode
>> parameter) to the compiled Assembly. I would only create the compiled
>> assembly if it was not previous registered in my Hashtable. The caveat is
>> you would need to ensure the code is thread safe...
>>
>> My other concern is if you compile the same snippet 4 times you actually
>> wind up with 4 "identical" yet individual compiled assemblies...
>>[color=darkred]
>>> My question is what happens to the dynamically created assembly when the
>>> method is done running?[/color]
>> I would expect the assembly to remain in the current AppDomain until that
>> AppDomain is unloaded, You might be able to handle the
>> AppDomain.AssemblyLoad & AppDomain.DomainUnload events to monitor its
>> lifetime.
>>
>> Notice there is no AppDomain.AssemblyUnload event, as you cannot unload
>> assemblies from an AppDomain without unloading the entire AppDomain.
>>[color=darkred]
>>> Or is it stuck in RAM until the ASP.Net process is recycled?[/color]
>> Based on how other assemblies work with an AppDomain that is correct.
>>
>>[color=darkred]
>>> 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?[/color]
>> I don't have a specific link to a complete sample, however you should be
>> able to create a "EvalProvider" AppDomain, load & instantiate
>> "EvalProvider" class & assembly in this second AppDomain, when you call
>> EvalProvider.Eval it should run in this second AppDomain.
>>
>> The following might get you started:
>>
>> http://msdn.microsoft.com/library/de...rp05162002.asp
>>
>> Its C#, however it should be easily converted to VB.NET, post if you need
>> help.
>>
>> One last item: The other major advantage of running the snippets
>> (EvalProvider.Eval) in its own AddDomain is that you can "lock down"
>> (security wise/permission wise) that AppDomain so that the snippet cannot
>> do stuff its not suppose to. Depending on who is writing the snippets
>> this can be a good thing :-)
>>
>> Hope this helps
>> Jay
>>
>>
>> "Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
>> news:%23Pmni7yAFHA.824@TK2MSFTNGP11.phx.gbl...[color=darkred]
>>>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
>>> ================================================== ==========================
>>> ====
>>>
>>>
>>>
>>>
>>>[/color]
>>
>>[/color]
>
>[/color]


Scott Allen
Guest
 
Posts: n/a
#15: Nov 19 '05

re: Eval code and AppDomains


Cool!! So all your questions are answered??

--
Scott
http://www.OdeToCode.com/blogs/scott/

On Thu, 27 Jan 2005 14:18:43 -0500, "Joe Fallon"
<jfallon1@nospamtwcny.rr.com> wrote:
[color=blue]
>Scott,
>Thanks!
>This was exactly what I was looking for.
>
>I was able to implement it successfully. It does exactly what I need it to
>do.
>Now I don't have to worry about separate AppDomains and dynamically creating
>an assembly multiple times.
>
>I simply added 2 references to my Class Library project.
>1. Microsoft.JScript
>2. Microsoft.VSA
>
>Then I added these 2 lines of code:
>
> Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
>Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
> Dim objResult As Object =
>Microsoft.JScript.Eval.JScriptEvaluate(sbCode.ToS tring, jEngine)
> If CBool(objResult) = True Then
> ...
>
>sbCode is the Stringbuilder that builds up the complex expressions.
>
>================================================= ===================
>
>On a side note:
>I read you article but I think I am missing something.
>What is wrong with the technique I am using above?
>Why did you talk about deploying assemblies and then come up with a dynamic
>assembly (which at least is only created once)?
>Doesn't the dynamic assembly require the same references as I added?
>
>I would appreciate it if you could clarify this as I would like to "put this
>to bed".[/color]

Joe Fallon
Guest
 
Posts: n/a
#16: Nov 19 '05

re: Eval code and AppDomains


Jay,
Thanks for the advice.
I have gone with Scott's solution and am very pleased with it.
--
Joe Fallon



"Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@msn.com> wrote in message
news:uaTpu0UBFHA.2016@TK2MSFTNGP15.phx.gbl...[color=blue]
> Joe,[color=green]
> > 1. Do you know of any other way to Eval a String to get a Boolean result[/color]
> JavaScript as Scott shows in the microsoft.public.dotnet.framework.aspnet
> newsgroup (not sure how this (languages.vb) newsgroup got left off that[/color]
half[color=blue]
> of this thread).
>
> Alternatively you could use a computed column in a DataTable, if your data
> is not already in a DataTable this may not work very well... The[/color]
Expresssion[color=blue]
> syntax in the DataSet OM is closer to VB, then JavaScripts, however with
> limits.
>
>[/color]
http://msdn.microsoft.com/library/de...ssiontopic.asp[color=blue]
>[color=green]
> > 2. Do you know if Eval will be a built-in function in ver 2.0 of the[/color][/color]
..Net[color=blue][color=green]
> > framework?[/color]
> Not that I know of
>[color=green]
> > 8. Since I am running in ASP.Net I would like to use the Cache to store
> > the[/color]
> I have not looked at it a lot, there is the Caching Application Block
>[/color]
http://msdn.microsoft.com/library/de...chingblock.asp.[color=blue]
>
> I normally simply keep the values in a Shared variables, however there is[/color]
no[color=blue]
> getting ride of old one...
>
> Hope this helps
> Jay
>
> "Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
> news:eOBOiBBBFHA.2584@TK2MSFTNGP09.phx.gbl...[color=green]
> > Jay,
> > Thanks for your input. You have helped me a lot in the past. I really
> > appreciate it.
> >
> > 0. BTW this dynamic assembly code only runs on a single page in a large
> > web site when a user enters a complex transaction. So I am not overly
> > concerned about it scaling (yet) since this will be a small percentage[/color][/color]
of[color=blue][color=green]
> > the total hits on the site.
> >
> > 1. Do you know of any other way to Eval a String to get a Boolean result
> > other
> > than dynamically generating the assembly as shown below?
> >
> > e.g. If I have a string such as "1=1" and I try to Cbool it I will get[/color][/color]
an[color=blue][color=green]
> > error.
> > Cbool("1=1") - error!
> >
> > But Cbool(1=1) will return True. (Note that this is not a string!)
> >
> > So the all the dynamic assembly does is execute my string and return[/color][/color]
T/F.[color=blue][color=green]
> >
> > This is the core of the dynamic code which is executed:
> > Dim boolResult As Boolean = Cbool((1=1))
> > Return boolResult
> > Notice how my original string is now represented as something that will
> > evaluate correctly.
> >
> > So, if there is some other way to get the same result I would like to[/color][/color]
know[color=blue][color=green]
> > about it.
> >
> > FYI - I have some complex rules that become simple to code as a long
> > Boolean string which when evaluated returns T/F which is the only result[/color][/color]
I[color=blue][color=green]
> > really need. When I tried coding these complex rules without building up[/color][/color]
a[color=blue][color=green]
> > string it quickly got unmanageable. There was a huge advantage to[/color][/color]
building[color=blue][color=green]
> > a string in the code. But now Evaling the string with a dynamic asembly
> > seems to be an issue.
> >
> > 2. Do you know if Eval will be a built-in function in ver 2.0 of the[/color][/color]
..Net[color=blue][color=green]
> > framework?
> >
> > 3. Good point about the Hashtable. If it stored both the string and the
> > result then it could act as a cache and dramatically reduce the dynamic
> > assembly creation by simply retrieving the result for each matching[/color][/color]
string[color=blue][color=green]
> > that has been previously computed. I think there would be a large number
> > of matches since the rules would not change that frequently and so the
> > strings would tend to be repeated for each transaction type.
> >
> > 4. The hashtable resolves the point about compiling the same snippet 4
> > times and creating 4 identical asemblies.
> > The original idea was to create the dynamic assembly and just "throw it
> > away" when it Eval(uated) the snippet.
> > But as I read more about it I learned you can't unload an assembly and[/color][/color]
so[color=blue][color=green]
> > I became concerned that I would be needlessly wasting memory. As I
> > understand it, ASP.Net monitors its AppDomain for "memory pressure"[/color][/color]
among[color=blue][color=green]
> > other things and will tear it down and build a new one automatically. I
> > guess my dynamic asemblies would just cause it to do this more[/color][/color]
frequently.[color=blue][color=green]
> > Agree?
> >
> > 5. Rick Strahl's article showed how to create a separate appdomain. I
> > downloaded his code and got it working within the current appdomain but[/color][/color]
it[color=blue][color=green]
> > failed when trying to create a new one. Interestingly, he was working on
> > the exact same issue today and had MS Support on the line for 2 hours
> > until the figured out the problem. Sounds like the same problem I was
> > having with his code so I am hoping I can get it working tomorrow. This[/color][/color]
is[color=blue][color=green]
> > a very tricky issue. Lots of people talk about it but Rick was the only
> > one who tried to abstract the problem and create a class that shows how[/color][/color]
to[color=blue][color=green]
> > do it. MS should do this since they are the ones who know what works and
> > what doesn't. The documentation is a bit sketchy and without MS Support
> > help Rick wouldn't have solved it either since there were no errors
> > returned from the code.
> >
> > 6. Good point on the security of a separate AppDomain.
> >
> > 7. I was considering setting a variable (count of hashtable?) that[/color][/color]
would[color=blue][color=green]
> > count the number of times I dynamically executed a snippet. When it
> > exceeded a certain threshhold I planned to tear down the separate
> > AppDomain and start over. Agree?
> >
> > 8. Since I am running in ASP.Net I would like to use the Cache to store
> > the hashtable. But the problem is the dynamic eval code is not in my[/color][/color]
code[color=blue][color=green]
> > behind pages. It is in my Business Object tier and that does not know
> > anything about the ASP.Net Cache. Any recommendations on how to store[/color][/color]
this[color=blue][color=green]
> > hashtable in my BO tier so that I will always have access to it?
> >
> > Thanks!
> > --
> > Joe Fallon
> >
> >
> >
> > "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_MVP@msn.com> wrote in[/color][/color]
message[color=blue][color=green]
> > news:%23pGE9q7AFHA.3616@TK2MSFTNGP11.phx.gbl...[color=darkred]
> >> Joe,
> >>> This code executes pretty frequently (maybe 4 times per transaction)[/color][/color][/color]
and[color=blue][color=green][color=darkred]
> >>> I
> >>> am concerned that I could be eating up RAM and not releasing it in my
> >>> ASP.Net application.
> >> Concern! Are you creating a dynamic assembly 4 times per transaction?
> >> Isn't that in itself causing a performance issue?
> >>
> >> I would consider keeping a Hashtable matching code snippets (the vbCode
> >> parameter) to the compiled Assembly. I would only create the compiled
> >> assembly if it was not previous registered in my Hashtable. The caveat[/color][/color][/color]
is[color=blue][color=green][color=darkred]
> >> you would need to ensure the code is thread safe...
> >>
> >> My other concern is if you compile the same snippet 4 times you[/color][/color][/color]
actually[color=blue][color=green][color=darkred]
> >> wind up with 4 "identical" yet individual compiled assemblies...
> >>
> >>> My question is what happens to the dynamically created assembly when[/color][/color][/color]
the[color=blue][color=green][color=darkred]
> >>> method is done running?
> >> I would expect the assembly to remain in the current AppDomain until[/color][/color][/color]
that[color=blue][color=green][color=darkred]
> >> AppDomain is unloaded, You might be able to handle the
> >> AppDomain.AssemblyLoad & AppDomain.DomainUnload events to monitor its
> >> lifetime.
> >>
> >> Notice there is no AppDomain.AssemblyUnload event, as you cannot unload
> >> assemblies from an AppDomain without unloading the entire AppDomain.
> >>
> >>> Or is it stuck in RAM until the ASP.Net process is recycled?
> >> Based on how other assemblies work with an AppDomain that is correct.
> >>
> >>
> >>> 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?
> >> I don't have a specific link to a complete sample, however you should[/color][/color][/color]
be[color=blue][color=green][color=darkred]
> >> able to create a "EvalProvider" AppDomain, load & instantiate
> >> "EvalProvider" class & assembly in this second AppDomain, when you call
> >> EvalProvider.Eval it should run in this second AppDomain.
> >>
> >> The following might get you started:
> >>
> >>[/color][/color][/color]
http://msdn.microsoft.com/library/de...rp05162002.asp[color=blue][color=green][color=darkred]
> >>
> >> Its C#, however it should be easily converted to VB.NET, post if you[/color][/color][/color]
need[color=blue][color=green][color=darkred]
> >> help.
> >>
> >> One last item: The other major advantage of running the snippets
> >> (EvalProvider.Eval) in its own AddDomain is that you can "lock down"
> >> (security wise/permission wise) that AppDomain so that the snippet[/color][/color][/color]
cannot[color=blue][color=green][color=darkred]
> >> do stuff its not suppose to. Depending on who is writing the snippets
> >> this can be a good thing :-)
> >>
> >> Hope this helps
> >> Jay
> >>
> >>
> >> "Joe Fallon" <jfallon1@nospamtwcny.rr.com> wrote in message
> >> news:%23Pmni7yAFHA.824@TK2MSFTNGP11.phx.gbl...
> >>>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[/color][/color][/color]
the[color=blue][color=green][color=darkred]
> >>> 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)[/color][/color][/color]
and[color=blue][color=green][color=darkred]
> >>> 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[/color][/color][/color]
no[color=blue][color=green][color=darkred]
> >>> 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[/color][/color][/color]
appdomain[color=blue][color=green][color=darkred]
> >>> 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
> >>>
> >>>
> >>>
> >>>[/color][/color][/color]
================================================== ==========================[color=blue][color=green][color=darkred]
> >>> ====
> >>> 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)
> >>>
> >>>[/color][/color][/color]
================================================== ==========================[color=blue][color=green][color=darkred]
> >>> ====
> >>> Dynamic Assembly code:
> >>>[/color][/color][/color]
================================================== ==========================[color=blue][color=green][color=darkred]
> >>> ====
> >>> 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
> >>>[/color][/color][/color]
================================================== ==========================[color=blue][color=green][color=darkred]
> >>> ====
> >>>
> >>>
> >>>
> >>>
> >>>
> >>
> >>[/color]
> >
> >[/color]
>
>[/color]


Joe Fallon
Guest
 
Posts: n/a
#17: Nov 19 '05

re: Eval code and AppDomains


Hey Scott,
No. I left you a bunch of questions at the bottom of my last message that
all referred to your article.

Just for my peace of mind - can you could address them?

I read your article but I wonder if I am missing something.
1. Is there anything wrong with the technique I am using above?

2. Why did you talk about deploying assemblies and then come up with a
dynamic
assembly (which at least is only created once)?

3. Doesn't the dynamic assembly require the same references as I added?
What is the advantage to it over the technique I used of adding references
to my project and adding 2 lines of code?


--
Joe Fallon



"Scott Allen" <scott@nospam.odetocode.com> wrote in message
news:1t7lv0t3otde0repq54lab3c15itk9j0a8@4ax.com...[color=blue]
> Cool!! So all your questions are answered??
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>
> On Thu, 27 Jan 2005 14:18:43 -0500, "Joe Fallon"
> <jfallon1@nospamtwcny.rr.com> wrote:
>[color=green]
> >Scott,
> >Thanks!
> >This was exactly what I was looking for.
> >
> >I was able to implement it successfully. It does exactly what I need it[/color][/color]
to[color=blue][color=green]
> >do.
> >Now I don't have to worry about separate AppDomains and dynamically[/color][/color]
creating[color=blue][color=green]
> >an assembly multiple times.
> >
> >I simply added 2 references to my Class Library project.
> >1. Microsoft.JScript
> >2. Microsoft.VSA
> >
> >Then I added these 2 lines of code:
> >
> > Dim jEngine As Microsoft.JScript.Vsa.VsaEngine =
> >Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
> > Dim objResult As Object =
> >Microsoft.JScript.Eval.JScriptEvaluate(sbCode.ToS tring, jEngine)
> > If CBool(objResult) = True Then
> > ...
> >
> >sbCode is the Stringbuilder that builds up the complex expressions.
> >
> >================================================= ===================
> >
> >On a side note:
> >I read you article but I think I am missing something.
> >What is wrong with the technique I am using above?
> >Why did you talk about deploying assemblies and then come up with a[/color][/color]
dynamic[color=blue][color=green]
> >assembly (which at least is only created once)?
> >Doesn't the dynamic assembly require the same references as I added?
> >
> >I would appreciate it if you could clarify this as I would like to "put[/color][/color]
this[color=blue][color=green]
> >to bed".[/color]
>[/color]


Scott Allen
Guest
 
Posts: n/a
#18: Nov 19 '05

re: Eval code and AppDomains


No problem - I'm in the middle of reverting back to my trusty old
newsreader but I've lost track of several threads!

1) No - nothing I can see, although I'd test the performance to see if
the created engine needs cached.

2) At the time I thought I needed a JScript project to do the Eval,
and I didn't want to add an extra project to a solution just to do an
eval.

3) Yes - the dynamic assembly requires the same references. I think
your approach is better being it is the simpler of the two. I imagine
they perform comparably.

--
Scott
http://www.OdeToCode.com/blogs/scott/


On Fri, 28 Jan 2005 17:29:27 -0500, "Joe Fallon"
<jfallon1@nospamtwcny.rr.com> wrote:
[color=blue]
>Hey Scott,
>No. I left you a bunch of questions at the bottom of my last message that
>all referred to your article.
>
>Just for my peace of mind - can you could address them?
>
>I read your article but I wonder if I am missing something.
>1. Is there anything wrong with the technique I am using above?
>
>2. Why did you talk about deploying assemblies and then come up with a
>dynamic
> assembly (which at least is only created once)?
>
>3. Doesn't the dynamic assembly require the same references as I added?
>What is the advantage to it over the technique I used of adding references
>to my project and adding 2 lines of code?[/color]

Joe Fallon
Guest
 
Posts: n/a
#19: Nov 19 '05

re: Eval code and AppDomains


Scott,
Thanks for all your help on this.
Good tip on caching the engine since it will get called regularly.
--
Joe Fallon



"Scott Allen" <scott@nospam.odetocode.com> wrote in message
news:7v5rv0p1qnu7lgcfjq88p0h7jtjkjun9h5@4ax.com...[color=blue]
> No problem - I'm in the middle of reverting back to my trusty old
> newsreader but I've lost track of several threads!
>
> 1) No - nothing I can see, although I'd test the performance to see if
> the created engine needs cached.
>
> 2) At the time I thought I needed a JScript project to do the Eval,
> and I didn't want to add an extra project to a solution just to do an
> eval.
>
> 3) Yes - the dynamic assembly requires the same references. I think
> your approach is better being it is the simpler of the two. I imagine
> they perform comparably.
>
> --
> Scott
> http://www.OdeToCode.com/blogs/scott/
>
>
> On Fri, 28 Jan 2005 17:29:27 -0500, "Joe Fallon"
> <jfallon1@nospamtwcny.rr.com> wrote:
>[color=green]
>>Hey Scott,
>>No. I left you a bunch of questions at the bottom of my last message that
>>all referred to your article.
>>
>>Just for my peace of mind - can you could address them?
>>
>>I read your article but I wonder if I am missing something.
>>1. Is there anything wrong with the technique I am using above?
>>
>>2. Why did you talk about deploying assemblies and then come up with a
>>dynamic
>> assembly (which at least is only created once)?
>>
>>3. Doesn't the dynamic assembly require the same references as I added?
>>What is the advantage to it over the technique I used of adding references
>>to my project and adding 2 lines of code?[/color]
>[/color]


Closed Thread


Similar ASP.NET bytes