3

I'm working on a website where a user can implement a C# code solution to a problem in a browser text area and submit it. The server will then compile that code together with a predefined interface I provide on the server. Think of it as a strategy design pattern; I provide a strategy interface and users implement it. So I need to compile a string and a predefined *.cs file together at run-time. Here's the code I have now that compiles only the string portion:

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");

CompilerParameters parameters = new CompilerParameters();
parameters.OutputAssembly = "CodeOutputTest.dll";   // need to name this dynamically.  where to store it?
parameters.GenerateExecutable = false;
parameters.IncludeDebugInformation = false;

CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, request.Code);

Users would submit something like this:

public class UserClass : IStrategy
{
     public string ExecuteSolution(string input)
     {
         // user code
     }
}

Security concerns aside (that's a heavy question for another day)...how can I compile this together with my predefined interface *.cs file? Or is there a better way of handling this?

5
  • Unless you have exceptionally good reason to trust all of your users, I would strongly suggest that you consider security concerns first. There's not a lot of point in determining how to solve the problem if you determine that there's no possible way to do it safely. Commented Jul 17, 2011 at 18:51
  • For security issue, I would suggest running in its own AppDomain. This would also allow you to 'unload' the assembly once its build. Depending on your volume, you could end up with hundreds/thousands/more assemblies held in memory. Commented Jul 18, 2011 at 12:51
  • @TheSean, I'm not sure just running the code in another AppDomain adds much security. Running it in another AppDomain under partial trust does. Commented Jul 18, 2011 at 18:07
  • Yes, security is definitely a concern here. But with a little research I think I should be able to run the code as a user with little to no privileges whatsoever. I noticed some properties on the CompilerParameters object, such as the Evidence or UserToken properties, that might aid in restricting the access granted to the code. Commented Jul 18, 2011 at 18:40
  • hey jturinetti, did you manage to do this? I need to implement something really similar. Commented Jun 14, 2014 at 5:13

1 Answer 1

3

CodeDomProvider.CompileAssemblyFromSource() is defined as

public virtual CompilerResults CompileAssemblyFromSource(
    CompilerParameters options, params string[] sources)

That means you can compile one assembly from multiple source files. Something like:

codeProvider.CompileAssemblyFromSource(parameters, request.Code, otherCode);

Another (possibly better) option is to reference already compiled assembly that contains the code you need. You can do this using CompilerParameters.ReferencedAssemblies:

parameters.ReferencedAssemblies.Add("SomeLibrary.dll");
Sign up to request clarification or add additional context in comments.

2 Comments

Pre-compile you interface! Also consider using CompilerParameters.GenerateInMemory = true, if you don't care about the DLL file.
The interface is precompiled :) It's in a separate project/DLL in my service layer. I will probably generate the compilation results in memory as well...thanks for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.