Click here to Skip to main content
12,948,566 members (61,420 online)
Click here to Skip to main content
Add your own
alternative version


23 bookmarked
Posted 19 Aug 2009

Compiling Source Code from a String

, 19 Aug 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
A method that uses a CodeDomProvider to compile program code from a string into an Assembly.


For an application I'm working on, I need the ability to allow the user to enter some text and have that text be compiled into a class just as if he had typed the class himself and passed it through a compiler. The application will wrap the text in some template code to form a (hopefully valid) program. But then it needs to be compiled so that the application can use the resultant class. The compiled Assembly doesn't need to be stored to disk for future reference, it can get garbage collected once the application is done with it. This method implements that functionality.


Among the various articles here on the Code Project that deal with this topic are:
Dynamic Creation Of Assemblies/Apps[^]
Compiling with CodeDom[^]

Although I had no need to use CodeDom to create the program code, these articles (and MSDN) provided a starting point for my eventual solution.

My Compile method

There really isn't much to the code:

  1. Check the input parameters
  2. Ask the system if the requested language exists
  3. Get a Provider for the requested language
  4. Get default parameters for the Provider's compiler
  5. Set additional parameters as required
  6. Compile the provided code
  7. Check for errors
  8. Return the compiled Assembly

Any Exceptions thrown by called methods will simply be passed along; there's no point catching them here.

public static System.Reflection.Assembly
    string          Code
    string          Language
    params string[] ReferencedAssemblies
    if ( System.String.IsNullOrEmpty ( Code ) )
        throw ( new System.ArgumentException
            ( "You must supply some code" , "Code" ) ) ;

    if ( System.String.IsNullOrEmpty ( Language ) )
        throw ( new System.ArgumentException
            ( "You must supply the name of a known language" , "Language" ) ) ;

    if ( !System.CodeDom.Compiler.CodeDomProvider.IsDefinedLanguage ( Language ) )
        throw ( new System.ArgumentException
            ( "That language is not known on this system" , "Language" ) ) ;

        System.CodeDom.Compiler.CodeDomProvider cdp
        System.CodeDom.Compiler.CodeDomProvider.CreateProvider ( Language )
        System.CodeDom.Compiler.CompilerParameters cp =
                ( Language ).CreateDefaultCompilerParameters() ;

        cp.GenerateInMemory = true ;

        cp.TreatWarningsAsErrors = true ;

        cp.WarningLevel = 4 ;

        cp.ReferencedAssemblies.Add ( "System.dll" ) ;

            ( ReferencedAssemblies != null )
            ( ReferencedAssemblies.Length > 0 )
            cp.ReferencedAssemblies.AddRange ( ReferencedAssemblies ) ;

        System.CodeDom.Compiler.CompilerResults cr =
            ) ;

        if ( cr.Errors.HasErrors )
            System.Exception err = new System.Exception ( "Compilation failure" ) ;

            err.Data [ "Errors" ] = cr.Errors ;

            err.Data [ "Output" ] = cr.Output ;

            throw ( err ) ;

        return ( cr.CompiledAssembly ) ;

Using the Code

In the application I'm working on, the user has the option to enter text into a TextBox just as he would write a string literal when writing a program. For instance, in a (C#) program I may write:

string text = "Hello, world!" ;

Ordinarily, in a TextBox, the Hello, World! would not be entered with the quotes, but in a program it's required. Things get even more complex if the text requires escapes:

string text = "Hello, \"Bob\"!" ;
string text = @"Hello, ""Bob""!" ;

Because mistakes can happen when you transcribe data, for this application I want to allow the user (a developer) to be able to copy-and-paste a string literal, exactly as he wrote it in a program, to the TextBox and have it passed through the compiler, just as it will be when his own application gets compiled.

This method:

  1. Accepts the Text from the TextBox
  2. Wraps it in a very simple C# program (notice how)
  3. Uses the CSharp (C#) compiler to compile the code into an Assembly
  4. Retrieves the Type defined by the program
  5. Gets the field that contains the compiled string literal
  6. Retrieves the string literal and returns it
private static string
    string Text
    string code = System.String.Format
        namespace TextWrapper
            public static class TextWrapper
                public const string Text = {0} ;
    ) ;

    System.Reflection.Assembly assm = PIEBALD.Lib.LibSys.Compile
    ) ;

    System.Type type = assm.GetType ( "TextWrapper.TextWrapper" ) ;

    System.Reflection.FieldInfo field = type.GetField
    ) ;

    return ( (System.String) field.GetValue ( null ) ) ;

Note: I intend to support as well.

CodeDom is in the System.Runtime.Remoting dll, so add a reference.


Overkill? I don't think so. For the samples above, sure, but consider more complex string literals, especially Regular Expressions, which often contain a lot of escapes and may be long enough to warrant being broken onto several lines. For example here's one that's not too big:

private static readonly System.Text.RegularExpressions.Regex HrefReg =
new System.Text.RegularExpressions.Regex
    "href\\s*=\\s*(('(?'uri'[^'#]*)?(#(?'id'[^']*))?')" +
) ;

To copy-and-paste this the usual way, I'd have to copy the two sections separately, and then remove the escapes. If I edit the string in the TextBox and then want to copy-and-paste it back, I have to reverse the steps, ensuring that I get all the escapes back where they belong.

Using a verbatim string literal would make it easier:

private static readonly System.Text.RegularExpressions.Regex HrefReg =
new System.Text.RegularExpressions.Regex
) ;

Using the technique described in this article, either of these string literals may be copied-and-pasted directly to the TextBox (or wherever) and parsed by the actual compiler that will be used to compile the strings later. If the text is edited away from the source code, it may be copied-and-pasted back without change.

Points of Interest

I wrestled for a long time with trying to load the compiled Assembly into a different AppDomain. I had some success and a lot of headache. Eventually I came across the following comment in the MSDN documentation of AppDomain.RelativeSearchPath[^]:

// Because Load returns an Assembly object, the assemblies must be
// loaded into the current domain as well. This will fail unless the
// current domain also has these directories in its search path.

So that's what was causing the headache. Plus, if loading an Assembly into a different AppDomain doesn't keep the Assembly from being loaded into the current one, then I don't see the point of trying.


2009-08-15 First submitted


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United States United States
BSCS 1992 Wentworth Institute of Technology

Originally from the Boston (MA) area. Lived in SoCal for a while. Now in the Phoenix (AZ) area.

OpenVMS enthusiast, ISO 8601 evangelist, photographer, opinionated SOB, acknowledged pedant and contrarian


"Using fewer technologies is better than using more." -- Rico Mariani

"Good code is its own best documentation. As you’re about to add a comment, ask yourself, ‘How can I improve the code so that this comment isn’t needed?’" -- Steve McConnell

"Every time you write a comment, you should grimace and feel the failure of your ability of expression." -- Unknown

"If you need help knowing what to think, let me know and I'll tell you." -- Jeffrey Snover [MSFT]

"Typing is no substitute for thinking." -- R.W. Hamming

"I find it appalling that you can become a programmer with less training than it takes to become a plumber." -- Bjarne Stroustrup

ZagNut’s Law: Arrogance is inversely proportional to ability.

"Well blow me sideways with a plastic marionette. I've just learned something new - and if I could award you a 100 for that post I would. Way to go you keyboard lovegod you." -- Pete O'Hanlon

"linq'ish" sounds like "inept" in German -- Andreas Gieriet

"Things would be different if I ran the zoo." -- Dr. Seuss

"Wrong is evil, and it must be defeated." –- Jeff Ello

"A good designer must rely on experience, on precise, logical thinking, and on pedantic exactness." -- Nigel Shaw

“It’s always easier to do it the hard way.” -- Blackhart

“If Unix wasn’t so bad that you can’t give it away, Bill Gates would never have succeeded in selling Windows.” -- Blackhart

"Use vertical and horizontal whitespace generously. Generally, all binary operators except '.' and '->' should be separated from their operands by blanks."

"Omit needless local variables." -- Strunk... had he taught programming

You may also be interested in...

Comments and Discussions

GeneralMy vote of 1 Pin
Izzet Kerem Kusmezer13-Apr-10 10:30
memberIzzet Kerem Kusmezer13-Apr-10 10:30 
GeneralRe: My vote of 1 Pin
Izzet Kerem Kusmezer13-Apr-10 10:31
memberIzzet Kerem Kusmezer13-Apr-10 10:31 
GeneralRe: My vote of 1 Pin
PIEBALDconsult13-Apr-10 11:03
mvpPIEBALDconsult13-Apr-10 11:03 
GeneralRe: My vote of 1 Pin
Izzet Kerem Kusmezer14-Apr-10 3:15
memberIzzet Kerem Kusmezer14-Apr-10 3:15 
GeneralRe: My vote of 1 Pin
PIEBALDconsult14-Apr-10 4:24
mvpPIEBALDconsult14-Apr-10 4:24 
GeneralRe: My vote of 1 Pin
Izzet Kerem Kusmezer14-Apr-10 4:27
memberIzzet Kerem Kusmezer14-Apr-10 4:27 
GeneralRe: My vote of 1 Pin
PIEBALDconsult13-Apr-10 11:04
mvpPIEBALDconsult13-Apr-10 11:04 
GeneralInteresting idea. Pin
Oakman24-Aug-09 3:45
memberOakman24-Aug-09 3:45 
GeneralRe: Interesting idea. Pin
PIEBALDconsult24-Aug-09 18:03
memberPIEBALDconsult24-Aug-09 18:03 
GeneralRe: Interesting idea. Pin
Oakman25-Aug-09 1:02
memberOakman25-Aug-09 1:02 
GeneralRe: Interesting idea. Pin
PIEBALDconsult26-Aug-09 4:17
memberPIEBALDconsult26-Aug-09 4:17 
GeneralMy vote of 1 Pin
keefb24-Aug-09 3:08
memberkeefb24-Aug-09 3:08 
GeneralRe: My vote of 1 Pin
PIEBALDconsult24-Aug-09 18:01
memberPIEBALDconsult24-Aug-09 18:01 
GeneralMy vote of 1 Pin
Dmitri Nesteruk20-Aug-09 5:10
memberDmitri Nesteruk20-Aug-09 5:10 
GeneralRe: My vote of 1 Pin
PIEBALDconsult20-Aug-09 7:56
memberPIEBALDconsult20-Aug-09 7:56 
GeneralIf you are interesed in the subject... Pin
Oleg Shilo19-Aug-09 17:14
memberOleg Shilo19-Aug-09 17:14 
GeneralRe: If you are interesed in the subject... Pin
PIEBALDconsult19-Aug-09 18:07
memberPIEBALDconsult19-Aug-09 18:07 
GeneralFormatting Pin
N a v a n e e t h19-Aug-09 4:11
mvpN a v a n e e t h19-Aug-09 4:11 
GeneralRe: Formatting Pin
PIEBALDconsult19-Aug-09 4:53
memberPIEBALDconsult19-Aug-09 4:53 
GeneralRe: Formatting Pin
johannesnestler19-Aug-09 5:11
memberjohannesnestler19-Aug-09 5:11 
GeneralRe: Formatting Pin
PIEBALDconsult19-Aug-09 5:27
memberPIEBALDconsult19-Aug-09 5:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170524.1 | Last Updated 19 Aug 2009
Article Copyright 2009 by PIEBALDconsult
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid