A better way to auto-run T4MVC when you build

Update: also see the newer post on this topic


T4MVC has always struggled with finding the right way of running automatically when you build.  Being a T4 template in your project, by default it just runs when you save it.  This is not great, because you really want it to rerun whenever you make a change that affects it: e.g. new controller action, new static file, …

So I had come up with a pretty crazy workaround (the AlwaysKeepTemplateDirty flag), described in details in this previous post (under “The T4 file automatically runs whenever you build”).  It’s a pretty hacky technique, which mostly works but has some nasty quirks:

  • You need to open and save it once to start the save ‘cycle’
  • You need to leave it open
  • It’s always marked as dirty, which is an annoyance.  The little ‘dirty star’ is always there, and when you close the project you’re always prompted if you want to save it, even though you didn’t change it.

Recently, Danish developer Joachim Lykke Andersen asked a question about this on StackOverflow, and then proceeded to find a pretty nice solution to it himself, which he has now blogged.  His solution relies on handling the VS OnBuildBegin event.  So basically, you just do a one time step, and then you don’t need to worry about it.  I won’t repeat all the details here, so get them on his post.

He also discusses the possibility off turning this into an Addin, which would be yet cooler.  And maybe with some convincing he will, so add a comment to his post 🙂


POLL: should we kill the AlwaysKeepTemplateDirty flag?

Given that this is a cleaner solution to this issue, I’m thinking of removing the AlwaysKeepTemplateDirty logic.  At the very least, I could turn it off by default in the T4MVC.settings.t4 (currently it’s on by default).  But in the end, it’s a hack and I wouldn’t mind getting rid of it altogether.

Would anyone object to this, or have concerns about this new approach?  Just let me know in the comments…

Comments (16)

  1. We don’t use the AlwaysKeepTemplateDirty trick, it requires to much setup.

  2. Matt Sherman says:

    It would be great not to have to pay attention to T4MVC after it’s been enabled.

    First choice, there would be hooks in VS to trigger it on any saves within /Controllers or /Views. Do these hooks exist?

    Second choice, the ability to flag a .tt file as "always run on build". This would setting be stored in the .csproj. Does VS support something like this?

    What Joachim describes sounds plausible. Esp as an Addin, a set-it-and-forget-it kind of thing. Simply toggle it on or off via a menu item.

    T4MVC is indispensable for me and anything that removes the little bits of friction would be great. 🙂

  3. David Ebbo says:

    @Matt: as far as I know, there is no such support to have a tt always run on build (otherwise, we’d use that!).  I think an Addin could probably be smart enough to detect when certain files are changed and take actions accordingly.  Admitedly, I don’t know much about wrting VS Addins 🙂

  4. betty says:

    An Addin would be nice, especially if it could add a property to each .t4 file letting you turn it on or off, if not I guess a list of filenames to do it on would work too.

    I do wonder if the t4 script can automatically install that macro though, could make things easier. I always find it a pain trying to get all our devs/designers running all the 3rd party things we use.

  5. Felipe Fujiy says:

    I preffer new approach. And completely remove old hack

  6. Paul Blamire says:

    I know it’s hacky but it works. You might forget initially to run the template but once you do it doesn’t cause any real harm.

    If the add-in approach works then great but until it’s proven to work over a period of time then my vote is for for changing the default

  7. James says:

    What’s wrong with writing a new build action and including a custom MSBuild block in your project file?

    Doesn’t require any user action other than clicking "Allow" to the security warning.

  8. Mel Grubb says:

    I use a pre-build technique for my Linq-to-SQL proxy class generator (http://tinyurl.com/melgrubb-l2st4).

    Basically, you just add a pre-build step to the project where the T4 template lives, similar to the following.

    "$(ProjectDir)……libsTextTemplatingTextTransform" "$(ProjectDir)AbcData.tt"

    Here, I’ve copied the TextTransform.exe into a solution-level folder called "libs" that also holds our StructureMap and RhinoMocks assemblies. It gets around the whole 32 vs 64 bit installation path problem for mixed teams.

  9. David Ebbo says:

    @James & @Mel: I don’t think going through an MSBuild action is possible here because the T4MVC template requires the VS host in order to run.  So you would not be able to run it outside VS using TextTransform.exe, which has its own minimal host.  The reason T4MVC needs the VS host is that it uses the VS Code Model to discover things like controller actions.

  10. I vote for the non-hacky version.  I really didn’t like it to start with.

  11. Jesse says:

    Doesnt tapping into the OnBuildBegin event cause the T4 template to always run? This seems like a pain when working with source control.

  12. David Ebbo says:

    @Jesse: yes, though that also happens with the current AlwaysKeepTemplateDirty hack.  Whether that causes source control pain depends on the system.  The generated files are identical if nothing has changed, so you shound’t see a diff.

    In a perfect world, we would know to only run it if something has happened in the app that affects T4MVC, but that would be pretty hard to pull off.

  13. Martin says:

    Joachim Lykke Andersen's link appears to be broken.  Fortunately, after a while I noticed your "newer post" link and found Wayne Brantley's solution.  Thanks!

  14. David Ebbo says:

    @Martin: yes, his blog no longer seems to work; I'm not sure why. I emailed him a while back but didn't hear back.

  15. Robert Stackhouse says:

    Do you have a link to a similar post to the now dead one?