views:

79

answers:

1

Is it OK to generate code like this on the fly? Or is this a major code smell? How can this be made better?

I'm new to web but I'm stumbling across this all the time and I don't really understand why.

// Create a js function that applies foo to each group of controls
foreach (KeyValuePair<string, Dictionary<Control, string>> pair in maps)
{
    js.Append(pair.Key);
    js.Append("=function(grid){Prm.remove_endRequest(");
    js.Append(pair.Key);
    js.Append(");if(grid && grid._element)"); //   ... blah blah blah

}
page.ClientScript.RegisterClientScriptBlock(page.GetType(), key + "Ajax", 
    js.ToString(), true);
+4  A: 

I don't see it as a smell until you start doing it all over the place.

Consider these changes, however, that will help out in the future:

  1. Write data-driven JS functions, and only dynamically generate the data that they need. This way, all your JS can be tucked away in a fast static file, and your server only sends the data. This is a better design change than (2) and (3) - and it really isn't that hard. Just think of the data that your current code generator needs, serve that data instead of the JS code, then wrap your JS code in "factory functions" that accept that data as input.

  2. Use templates for the JS code just as you use templates for HTML. This way you don't have to munge around in C# flow control / data control code when you really just want to change some variable names. I would suggest naming template files with the name of the view that it assists. If you have Home.aspx then perhaps you will have JS code templates Home_DoCrazyGridThing.js, Home_DoOtherCrazyThing.js. You can write a simple template engine or use one of many existing such.

  3. Create a thin layer over generating code so that it's obvious what you're doing to the maintainer. That is, have a JSCodeGenerator class with varying levels of intelligence (understands the language OR just allows you to dump string in it OR interfaces with the emplate engine from (2)).

Frank Krueger