We want to give a user a graphical format to design conditional statements on some data. Our application would take that graphical format, translate it into C#, compile it, and run the conditional statement against some data, returning a Boolean.
The catch is that these conditional statements need to be written and compiled (and, of course, executed) at runtime, since we won’t be rebuilding the application each time the user creates a new conditional statement.
We thought about using LINQ expression trees, but a compiled LINQ expression tree can’t be saved, which means we need to recompile each time the conditional statement is going to be executed.
We think a better alternative is to use CodeDOM to compile the conditional statement as a .dll (they would be converted into a static method of a static class that takes, as a parameter, the data to run against the conditional statement). This allows us to save the compiled statement, and we could load and unload the .dll at runtime. Also, it’s easier to generate the C# if-statement than the LINQ expression tree.
Alternatively, we could use Roslyn to generate the .dll’s. This is reportedly faster than CodeDOM, but Roslyn is still in CTP.
Are there hidden pitfalls, or a general pattern for doing this, that we should know about? Aside from being very careful to generate only functions that test against data (and does not modify data or allow invoking any other functions), what else should we be careful about? Will loading and unloading (potentially hundreds of) these .dll’s cause issues? If each .dll is given its own unique namespace, will loading and unloading (potentially hundreds of) them leave artifacts?
we need to recompile each time the conditional statement is going to be executed
I don't think this is going to be a problem. Unless you need to compile many expressions per second, the performance hit of compiling an expression tree shouldn't be noticeable.
we could load and unload the .dll at runtime
Not really. You can't unload a normal assembly in .Net. A collectible assembly will be unloaded once it's detected it's not used, but that works only for dynamic assemblies (not ones loaded from disk). You can also unload an AppDomain, which also unloads all assemblies loaded into that domain, but that means running your statements in a separate AppDomain.
Also, it’s easier to generate the C# if-statement than the LINQ expression tree.
Does that really matter? You're going to write that code only once. And I don't think creating the if statement is actually that much harder with expression trees, once you know how to do it. Especially when compared with Roslyn, which is extremely verbose when used for code generation (because that's not its primary use case).
[Roslyn] is reportedly faster than CodeDOM, but Roslyn is still in CTP.
Could you quote a source for that? But I really doubt that the speed of compilation would be actually important for you.
If each .dll is given its own unique namespace …
That doesn't make any sense, a DLL doesn't have a namespace. In fact, the CLR doesn't really deal with namespaces, it just sees a class that has dots in its name.