[Mono-list] General .NET Q

Jonathan Pryor jonpryor@vt.edu
Wed, 24 Mar 2004 22:15:21 -0500


On Wed, 2004-03-24 at 21:05, Shawn Vose wrote:
> Does anyone know if the following is possible:
> Taking a snippet of .NET c# code, maybe a function, and storing it in a
> mysql db
> to be later called by another piece of code and executed?
> I was asked this question by a client and I dont have the slightest clue
> on how to answer this. My initial answer is no because it would have to
> be compiled into the calling class; however, I am thinking that
> system.reflection would be able to help me.

Is it possible?  Yes.  Will System.Reflection do it?  It depends.  It
can't do it alone, though.

The easiest thing to do would be to:
1.  Define an interface
2.  Use System.CodeDom to (a) generate skeleton C# code, (b) include the
    code from the database into the CodeDom code, and (c) compile the
    code into an assembly.  The CodeDom code should implement the 
    interface defined in (1).
3.  Load the assembly at runtime
4.  Instantiate the type from the assembly at runtime, through the 
    numerous mechanisms .NET provides (Activator.CreateInstance, etc.)
5.  Cast the type created in (4) to the interface defined in (1)
6.  Invoke the code via the interface method.

A Variation would be to use a delegate instead of the interface.

A pitfall with this framework is that all methods defined in the
database must conform to a single interface, so you couldn't have
methods with different argument lists and return types defined this way.

To work around that, you could use System.Reflection.MethodInfo, but
this complicates your client code as you need not only need to know what
function to call, but also what arguments to provide it, what it
returns, etc.  This can be done, it's just not as simple or as fast as
the above solution.

(Regarding performance, CodeDom generation will be slow, but it can't be
avoided.  Method invocation also can't be avoided, but
delegate/interface invocation is *much* faster than MethodInfo.Invoke,
so if this code will be invoked frequently, a well-defined
delegate/interface would be preferred.)

 - Jon