Dynamically enter in, compile, and execute VB.NET source code

I recently worked on a project where the business rules would not be finalized
until after the project was scheduled to be completed :-(. Mainly it was a data
entry system that needed to validate the input data. Standard stuff. If field A
is missing give a message, If Field B was "X" and field C was not "Y", give a
message...

My solution was to store the names of the TextBox, DropDownList, CheckBox, etc.
controls used for inputting data in a database. Along with each control was its validation
code. Yep, the validation code was the complete VB.NET source code to
be executed to validate the control's data.

When the user clicked the Save button I read the control's code from the
database, compiled it and executed it! This way, as business rules became known
they could br added to the database and the production code never needed to
change. Is this the optimal way of creating applications? No, but it worked and
actually performance was respectable.

The attached sample code shows how to dynamically read VB.NET source code from a
text file, compile it, and then execute it.

Download the code, make sure the Source.txt file is in the bin subfolder,
and step through the code.

The guts of the code is in the btnRun_Click event handler. First an instance of
the VB compiler is created using the System.CodeDom.Compiler
namespace's ICodeCompiler interface and the
Microsoft.VisualBasic.VBCodeProvider class' CreateCompiler
method.

Next, a CompilerParameters object is created to
pass paramteres into the compiler. Several parameters are set to various DLLs.
Then the CompilerParameters object's GenerateInMemory
property is set to tell the compiler not to write its results to disk.

The source code is obtained from the text file and passed into the compiler
object's CompileAssemblyFromSource method along
with the CompilerParameters. The results of calling this method is a
CompilerResults object which contains the results of compilation.

Compilation results are checked to see if there were any errors by examining the
HasErrors property of the CompilerResults
object's Errors collection.

If the source code compiled cleanly, a reference is obtained to the compiled
assembly. Since the source code in this sample contains a class called DymanicCode,
an instance of that class is created and stored in a variable named objTheClass.
Note that this is a hard tie between the source code and the application's
code.

The DynamicCode class contains an ExecuteCode method that requires
one parameter. So, the next step is to create the parameter and set it's value.
Then the InvokeMember method is called on the objTheClass
to call the ExecuteCode method with its parameter.