At my day job, we are working on a large enterprise system. One of the feature areas of this product is an array of different charts of performance metrics. All of these charts accept a common set of parameters, and generate some json that is used by our client side to render a chart for the requested metric.
At the moment, we are using a standard MVC controller to define the actions necessary to calculate and collate these stats. The other day, we were kicking around the idea of how we would be able to add new charts in for a client, after they already have the product installed. With the current design we are using, there isn’t really an easy way to do that without dropping in the updated build that has the updated controller. That’s not really an ideal situation, since reinstalling and reconfiguring the application is kind of a heavy-handed approach when all we want to do is add a couple of new charts in, without impacting the rest of the application. It also doesn’t give us many options if our customer, for whatever reason, wants to disable certain charts.
Probably, what we’ll end up doing, is using the database to define the chart calculation SQL, either using by storing the SQL statements to retrieve the metrics in a table, or via stored procedures. I’ll admit, I’m not crazy about this approach, since I’ve worked on a couple of other products that used this method, and I have some slight PTSD from trying to troubleshoot convoluted SQL that was poorly written and not checked into source control other than in the master database creation script. With a sane process, this will probably be an effective option; one of the reasons we are likely going to need to go this route is that we are developing parallel .NET and Java versions, due to API restrictions of the underlying technology stacks that we are targeting, while trying to use a common UI and database.
This did get me thinking about how it would be possible to dynamically populate the actions of an MVC controller. I had come across some posts on CSScript, which is a library which allows you to run arbitrary C# code interpretively. Depending on how you use it, you can load up entire classes, methods or even statements, and invoke them at run-time, without the script code being compiled and embedded in your .dll. So, theoretically, it should be possible to define the controller action that calculates the metrics for a given chart in a CSScript file, load that up, execute it using the CSScript interpreter, passing any parameters needed in, and return the results.
The other piece of this is figuring out how to get an MVC controller to accept action routes that are not explicitly defined for it. Fortunately, with the latest version of MVC, you are able to tweak the default behavior of the controller to a considerable degree, if you are willing to delve into overriding some of the virtual methods the Controller class gives you access to. So, after a little digging, I was able to figure out a slightly crazy way to wrestle MVC into doing what I wanted it to do – accepting dynamic controller actions, executing a scripted action, and then returning the result to the webpage.
This is a very quick and dirty example, really just a proof of concept prototype, so I make no promises as to its performance or robustness. But, it was cool to figure out that such a thing was possible, and I figured that I would share it as a jumping-off point in case anyone else encounters a similar crazy requirement. The code is available on my GitHub repository, at https://github.com/ericrrichards/MVCScriptedController.git.