Dynamic Code Generation and Analysis Using Microsoft Roslyn CTP
Microsoft recently released their Roslyn Community Technology Preview. The Roslyn project gives developers access to the Visual Basic and C# compiler information through APIs.
As described by Microsoft, “the Roslyn CTP previews the next generation of language object models for code generation, analysis, and refactoring, and the upcoming support for scripting and interactive use of VB and C#.” While that statement may seem pretty innocuous, this project is actually a very big deal. This will give developers greater ways to dynamically analyze code, refactor and generate code on the fly.
Why Roslyn is Important for Business Software:
Let’s say I have a Lead Receiver Service that accepts leads from a client. My Lead Receiver may accept SOAP or Restful data transfers from a client. The Receiver will process the Lead, store the Lead in the data store and send notifications that a Lead was received. When the service fails and logs exceptions, I will have to analyze the source of the exception and fix it. With tools like the Roslyn project, I will be able to write a Lead Receiver Monitor that can monitor the Lead Receiver, receive error notifications, analyze the failures and fix application errors when they occur. The Lead Monitor can change the structure of the application, recompile it with the code fix and publish the change. We will be one step closer to having self-healing application systems. As Neo eloquently put it in the Matrix trilogy; it will be Programs hacking Programs.
Here is a simpler example:
I have a product that I sell with options that need to be dynamically generated based on its current configuration. For example, I am a car dealer with certain models having only certain colors available. Certain packages will only apply if I have a 4 X 4 instead of a sedan or a compact. I can have the options dynamically configured at runtime by writing a C# macro to populate the list of options based on the code in the macro.
Let’s implement this scenario to see how it will look.
Pre-Requisites
- The Roslyn CTP requires the Visual Studio 2010 SP1 SDK
- Then you can download and install the Roslyn October 2011 CTP. Do this here.
I created an ASP.NET/MVC3 Web Project and added references to the Roslyn CTP libraries. I added the following libraries:
- Roslyn.Compilers.dll
- Roslyn.Compilers.CSharp.dll
- Roslyn.Services.dll
- Roslyn.Services.CSharp.dll
View Model
Our Clickpoint Motors Data model will simply have a Car that will have the following fields:
- VehicleModel : We have 3 main models for Sale : Sedans, Roadsters and Trucks
- Color: the Car’s color
- Price: the Price of the vehicle
OptionsMacroText : This will hold the code that we will use to generate the Available Options List Dynamically.
Generating the Options
We will use an interface with a method signature as our contract for generating the vehicle options. Our interface will have one method that takes in a Car Model parameter named ‘car’ and returns a Generic List containing strings.
Here are the steps we will perform when generating options
- We will generate a class that implements the IGenerateOptionsMacro interface
- Combine it with the source code from our Car configurations
- Compile it and store it into an assembly that we can then use to generate an instance of the class at runtime and call the GenerateOptions method using our CarModel object as a parameter.
I create my new car configurations and select my Vehicle Model, Color, Sports Package and Enter the code into my options macro. By convention, my GenerateOptions method in my Macro class will have a local variable named options, which is of type List<string>.
After creating the Car Configurations, we view the car inventory to see what we have available in our Showroom. When we select “Show Options” on the Inventory Page, we will dynamically generate the options available based on the car’s macro code.
If we look at the ShowOptions action in our CarController class, we can take a closer look at how the options are dynamically generated.
In our ShowOptions controller we do the following:
- 1. Find the Car with the given Id. Get the Factory Object that we use to create the instance of the class that implements IGenerateOptionsMacro
- Create an instance of the class.
- Call the GenerateOptions function and pass the CarMode as a parameter.
- Return the options list back to the view to be displayed
We implement the source code generation and compilation in our GenerateOptionsMacroFactory
Class. The GenerateOptionsMacroFactory class is where we do all the heavy lifting of creating the Source code, compiling it and then creating an instance of the Macro class from the compiled assembly.
Here is the interface signature.
And the Implementation
Once the instance of the IGenerateOptionsMacro object is created, all we have to do is call the GenerateOptions method and it will spit out our list. We use the Roslyn.Compilers.CSharp library to compile our source code into an assembly. Then we use the assembly to generate an instance of our GenerateOptionsMacro class. Once we have an instance of the class, we can easily generate the options list. All done dynamically at runtime!
Summary
So, we just showed how we could dynamically generate code using the Microsoft Roslyn CTP.
I’ve put up the source code for this demonstration on GitHub:
https://github.com/kmariano/ClickpointRoslynCTPDemo