15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

440 ❘ ChaPTer 18 Assemblies<br />

Console.SetOut(temp);<br />

}<br />

returnData = writer.ToString();<br />

}<br />

}<br />

}<br />

return returnData;<br />

code snippet DynamicAssembly/CodeDriver.cs<br />

The method CompileAndRun() requires a string input parameter where one or multiple lines of <strong>C#</strong><br />

code can be passed. Because every method that is called must be included in a method <strong>and</strong> a class, the<br />

variables prefix <strong>and</strong> postfix defi ne the structure of the dynamically created class Driver<br />

<strong>and</strong> the method Run() that surround the code from the parameter. Using a StringBuilder , the prefix ,<br />

postfix , <strong>and</strong> the code from the input variable are merged to create a complete class that can be compiled.<br />

Using this resultant string, the code is compiled with the CSharpCodeProvider class. The method<br />

CompileAssemblyFromSource() dynamically creates an assembly. Because this assembly is just needed in<br />

memory, the compiler parameter option GenerateInMemory is set.<br />

If the source code that was passed contains some errors, these will show up in the Errors collection<br />

of CompilerResults . The errors are returned with the return data, <strong>and</strong> the variable hasError is set<br />

to true .<br />

If the source code compiles successfully, the Run() method of the new Driver class is invoked. The<br />

invocation of this method is done using refl ection. From the newly compiled assembly that can be accessed<br />

using CompilerResults.CompiledType , the new class Driver is referenced by the driverType variable.<br />

Then the InvokeMember() method of the Type class is used to invoke the method Run() . Because this<br />

method is defi ned as a public static method, the BindingFlags must be set accordingly. To see a result of<br />

the program that is written to the console, the console is redirected to a StringWriter to fi nally return the<br />

complete output of the program with the returnData variable.<br />

Running the code with the InvokeMember() method makes use of .<strong>NET</strong> refl ection.<br />

Refl ection is discussed in Chapter 14.<br />

The Click event of the WPF button is connected to the Compile_Click() method where the CodeDriver<br />

class is instantiated, <strong>and</strong> the CompileAndRun() method is invoked. The input is taken from the TextBox<br />

named textCode , <strong>and</strong> the result is written to the TextBlock textOutput .<br />

private void Compile_Click(object sender, RoutedEventArgs e)<br />

{<br />

var driver = new CodeDriver ();<br />

bool isError;<br />

textOutput.Text = driver.CompileAndRun(textCode.Text, out isError);<br />

if (isError)<br />

{<br />

textOutput.Background = Brushes.Red;<br />

}<br />

}<br />

c o d e s n i p p e t D y n a m i c A s s e m b l y / D y n a m i c A s s e m b l yW i n d o w. x a m l . c s<br />

Now you can start the application; enter <strong>C#</strong> code in the TextBox as shown in Figure 18 - 8, <strong>and</strong> compile <strong>and</strong><br />

run the code.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!