Big Template refactoring

Jun 5, 2011 at 5:58 PM
Edited Jun 6, 2011 at 6:29 AM

Hi all,

There are two active features in the Issue Tracker

  • Silverlight - support "Edge applications" (REST/SOA)
  • Implement Encapsulated Invoke model
that raise the same problem - templatate aren't modular enough.
As an example, there is a DataPortal_Fecth.asp file but nevertheless DataPortal_Fecth method is also generated in other files. When I want to change how DataPortal_Fetch is generated, I must do it in several places. This is a bad programing practice as one must make sure not to miss a spot and to change all instances the same way. Of course a specialised file for Silverlight is acceptable and advisable. What isn't admissible is handling all the other files that take charge of generating this method by themselves in some harcoded way.
Modular is also used as opposed to monolitic. Reverting to DataPortal method generation, if I detach all DataPortal generation from each main object template, it's easier to introduce new logic like
if Silverligth do this
if simple DAL, do that
if interface DAL do another thing
Last but not least, template specialization (like the DataPortalFetchSilverlight template) is also a result of modularity.
Revising the templates has been a big task.
1) First of all they used a Java style - Curly brackets (or braces) at the end of the line instead of the beginning of next line. There was also a tendency to write lines as long as possible. At first I thought this was a CodeSmith requirement. Then I found it wasn't. So everything was restyled to a more familiar and legible presentation.
2) Some people don't care if program lines have trailing spaces, or indentation is wrong, or tab are mixed with spaces, or program files have extra blank lines or don't have enough blank lines. I do. And that was a nightmare to fix. And it's only 90% correct.
3) Converting the templates for CSLA.NET 4 was a very big task as CslaGenFork itself was expanding to support some flexibility. In mid course I found out that I could use the templates to validate and issue warnings to the user or to stop object generation in case some fatal error was found. Before that, the common problem was a template compilation error that usually is as friendly as a mad grizzly bear. These validations reduced the number of generation crashes.
4) In order to support the advanced features needed by CSLA.NET post 2.0 and also the advanced features of CslaGenFork a lot of supporting functions were needed:
  • format a property declaration according to how it is declared (classic, auto, managed, etc)
  • handle lazy load scenarios
  • etc
  • etc
  • etc
Doing it on the templates would result in enormous template files and hard to read on top of that. So a specialized class CslaTemplateHelper was written. This solution was inherited from the riginal CslaGen but was greatly extend up to the point a generating incompatibilities with former templates. So a new class was made, just for projects targeting CSLA.NET 4.
The worst part is that (almost) all of this was happening at the same time: restyling, adding new features to CGF, rewriting support code. Some tasks made the styling problem even worst, new indents were needed but they weren't set at the correct indentation level. The template was in such a bad shape that it would take too long to restyle.
All the above tasks are mostly done. What needs to be done is a new refactoring, in order to make the whole thing modular and more manageable. So you can expect:
  • an increase in the number of templates
  • involuntary feature break (aka bugs)
  • powerfull features in CslaGenFork
Is this reafctoring absolutely need for the new features? Yes and no.
Yes - it's the fastest and safest way to get there.
No - we could do it without resorting to refactoring, but every single problem would take an eternity to solve.
Jun 5, 2011 at 6:04 PM

This refactoring won't affect SProc generation - this is an even bigger problem and won't be solve in the short term.

The supporting code must be redone. It is written in a very complicated way. On top of that, it must be adapted to new requisites:

  • multi server support (Oracle, Firebird, PostgreSQL, MySQL, SQLite)
  • generate SProcs and inline SQL queries
Jul 14, 2011 at 10:48 PM

I'd like to see this refactoring done as the more modular the templates and the better the generator code, the easier it will become to make the templates work well and the quicker it will be to make fixes/changes if CSLA changes

For instance, the Silverlight LazyLoad issue I've put a work item up for - this could be fixed in the templates quickly and easily if the templates were modular - but at the moment I'd have to download the src and rebuild CSLAGenFork just to make the tweak

My opinion is that a lot of 'selector' code goes into each template, and that possibly some of this can be moved into 'selector' templates or onto properties in the metadata. For example, both the AddItem and AddItemAsync are included in the CollectionBusinessMethods template based on CurrentUnit.GenerationParams - but this test is repeated in the AddItem and AddItemAsync templates - which file should be 'selecting' which code is used? I think either CollectionBusinessMethods.asp or possibly a sub-template AddItem.Selector.asp which chooses which code file to include based on metadata. Another example is 'useAuthz' and 'needsBusiness'. These flags are set by code in some of the templates - a job which should really be performed using properties on the metadata. This keeps the templates clutter free - too much coding in the templates should be avoided imo.

I have noticed that some of the templates seem to take a long time to generate - could this be due to the complexity of the templates and the amount of parsing that is required to build the objects?

Jul 18, 2011 at 11:58 PM
Edited Jul 19, 2011 at 12:06 AM

The generation of lazyload code is pretty complex and that's why I chose not to put it in the templates but is the CslaTemplateHelperCS.cs file. Can it be simplified and put in modular templates? Good question, never though about it but then again modular templates is pretty new and I guess it can be explored a lot more.

Abou the the time the templates take to generate, I never timed it. When I'm doing tests, I disable generation for all except for the subject under test. You must remember some template run a lot of validation before starting any usefull work.

Anyway each stereotype is compiled just once and kept in cache. The more code is in the templates, the longer it takes to compile. If a lot of code is in the CslaTemplateHelperCS.cs class, that code is already compiled. The more code I take from there to the templates, the longer the templates will take to compile. So... there is a positive and a negative side to everything.