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]