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.