One of the many benefits of the Roslyn compiler-as-a-platform approach is that we can use it within our own applications to enable interesting scenarios like code-based configuration or scriptable behaviors. Roslyn provides several facilities for making this possible including a compilation API, access to syntax and semantic information, and a dedicated scripting API. In addition, Roslyn also powers the execution of C# scripts (typically ending in the
.csx extension) by providing a script runner executable that's basically a thin wrapper around the scripting API I just mentioned. This gives developers many different options for how to introduce the power of code-driven functionality to their codebase. This post takes a look at two such options and why you might want to use one over the other. We'll also consider some of the fundamental reasons why there are tradeoffs at all and what could be done to improve the situation.
I've written a lot of T4 templates, and while they work well enough for compile-time code generation, they're never much fun to write. Recently however I've noticed an even bigger problem with T4 templates now that Visual Studio is becoming less and less a required part of the build process (more on this in a minute). Thankfully, the Roslyn team has done an excellent job of packaging the Roslyn compiler into an easy to consume scripting package. By combining that scripting support with some Visual Studio extensibility, we can provide a code generation alternative that relies on Roslyn scripts written in plain old C# (VB.NET script support coming soon).
Just a quick note that most of the functionality in LINQPad.CodeAnalysis can now be found in LINQPad 5 (as of 5.02 beta). When using LINQPad 5, the syntax tree and syntax visualizer are both found under the "Tree" tab after executing a query. This tab is available for any query and you can also dump a
SyntaxNode explicitly by calling
.DumpSyntaxNode(). The integration in LINQPad 5 is also tighter than a plugin allows and lets you highlight the original query as you highlight nodes in the syntax tree as well as other UI improvements. I'd like to thank Joseph Albahari for making this integration possible and for tweaking things to provide the best possible experience:
I am very proud to announce my newest project, Wyam. It's a static site and content generator built from the ground up to be modular and flexible.
T4 templates provide a powerful way to generate code at design time (and sometimes at compile time if you set up Visual Studio appropriately). The traditional way of accessing the code of your solution from within a T4 template is to get the Visual Studio API (called DTE). This has always seemed like a bit of a kludge to me and feels a little too far removed from the code and what it represents. We now have another option by using the .NET Compiler Platform from within a T4 template to parse, query, and output content based on the files in our solution.
LINQPad.CodeAnalysis is a library that contains a set of .NET Compiler Platform helpers and utilities for LINQPad. Because it is so low ceremony but also has advanced functionality like debugging, data source connections, and advanced output and visualization, LINQPad provides an ideal platform for quickly experimenting, exploring, and working with the .NET Compiler Platform.
Scripting support in the .NET Compiler Platform (formerly known as Roslyn) has been a long time coming. It was originally introduced more than a year ago and then removed while the team considered what the ideal API should look like. It was recently reintroduced into the master source branch on GitHub, though as of this blog post it still isn't available on the nightly MyGet feed or on NuGet. In this post I will explain how to obtain and build the new scripting bits (including on a system without Visual Studio 2015 - it can actually be built using only Visual Studio 2013), introduce some of the scripting functionality, and show some scenarios where this might be helpful in your own applications. I also want to caveat this post by saying that it may go out of date quickly. The .NET Compiler Platform is under heavy development and it is changing frequently, including the public API. While I wouldn't expect any sweeping changes in the scripting support at this point, many of the details are subject to change.