Up until now, we’ve mostly looked at how we can use Roslyn to analyze and manipulate source code. Now we’ll take a look at finishing the compilation process by emitting it disk or to memory. To start, we’ll just try emitting a simple compilation to disk and checking whether or not it succeeded.
After running this code we can see that our executable and
.pdb have been emitted to
Debug/bin/. We can double click
output.exe and see that our program runs as expected. Keep in mind that the
.pdb file is optional. I’ve only chosen to emit it here to show off the API. Writing the
.pdb file to disk can take a fairly long time and it often pays to omit this argument unless you really need it.
Sometimes we might not want to emit to disk. We might just want to compile the code, emit it to memory and then execute it from memory. Keep in mind that for most cases where we’d want to do this, the scripting API probably makes more sense to use. Still, it pays to know our options.
Finally, what if we want to influence how our code is compiled? We might want to allow unsafe code, mark warnings as errors or delay sign the assembly. All of these options can be customized by passing a
CSharpCompilationOptions object to
CSharpCompilation.Create(). We’ll take a look at how we can interact with a few of these properties below.
In total there are about twenty-five different options available for customization. Basically any option you have within the Visual Studio’s project property page should be available here.
There are a few optional parameters available in
Compilation.Emit() that are worth discussing. Some of them I’m familiar with, but others I’ve never used.
xmlDocPath– Auto generates XML documentation based on the documentation comments present on your classes, methods, properties etc.
manifestResources– Allows you to manually embed resources such as strings and images within the emitted assembly. Batteries are not included with this API and it requires some heavy lifting if you want to embed
.resxresources within your assembly. We’ll explore this overload in a future blog post.
win32ResourcesPath– Path of the file from which the compilation’s Win32 resources will be read (in RES format). Unfortunately I haven’t used this API yet and I’m not at all familiar with Win32 Resources.
- There is also the option to
EmitDifferencebetween two compilations. I’m not familiar with this API, and I’m not familiar with how you can apply these deltas to existing assemblies on disk or in memory. I hope to learn more about this API in the coming months.
That just about wraps up the Emit API. If you have any questions, feel free to ask them in the comments below.