Mind if my MVC T4 template changes your code a bit?

Update: Please see this post for what came out of this ‘poll’, and for a pointer to the newest T4 template on CodePlex.

When working on my MVC T4 template, I was not able to use reflection to discover the Controllers and Actions, because the code that the template generates is itself in the same assembly as the controllers.  So that causes a bit of a chicken and egg problem.

Instead, I had to get out of my element and learn something I was not familiar with: the Visual Studio File Code Model API.  It’s very different from using reflection, because instead of working at the assembly level, you work at the source file level.

You have to first locate the source file you want to look into.  You can then ask for the namespaces that it contains, and the classes that they contain, and finally the various members in those classes.  To be honest, I find this API quite ugly.  It’s a COM interop thing with a horrible object model that looks like it grew organically from version to version rather than having been designed with usability in mind.  So all in all, I used it because I had to, but the whole time I was wishing I could use reflection instead.

But then I made an important realization.  Ugly as it is, this object model supports something that would never be possible with reflection: it lets me modify the source code!

If you look at my previous post, I wrote “But to make things even more useful in the controller, you can let the T4 template generate new members directly into your controller class.  To allow this, you just need to make you controller partial”.  And I have logic in the template that tests this, and does extra generation if it is partial, e.g.

if (type.ClassKind == vsCMClassKind.vsCMClassKindPartialClass) { ... }

But instead, I have now realized that I can turn this check into an assignment, and change the class to partial if it isn’t already!

type.ClassKind = vsCMClassKind.vsCMClassKindPartialClass;

Likewise, I have scenarios where I can do cool things if the Controller actions are virtual, and I can just change them to be with a simple line:

method.CanOverride = true;

To be clear, those statements actually modify the original source file, the one that you wrote.  While this is certainly powerful and opens up some new doors, it also raises a big question which is the main purpose of this post:

Do you mind if the T4 template makes these small changes to your code?

We’re only talking about pretty harmless things (making classes partial and methods virtual), but I know developers can get nervous if even small changes magically happen in their source files.

So please tell me how you feel about this, e.g. is it more:

  1. It’s harmless, go for it if it makes the template more useful

  2. Undecided. I don’t really like it, but maybe I’ll put up with it.

  3. No way I’ll use this template if it messes with my files in any way. I may even sue you!

Tell me where you stand, and please don't sue me.

Comments (40)

  1. My vote is for #2.  I don’t like the idea, but if it’s really useful I might put up with it.

  2. sjnaughton says:

    my vote is #1, but is there a way for it to popup a dialogue to ask permission or even let you know it has happend?

    Steve 😀

  3. Simone says:

    It depends: if it’s only marking the class partial there is no problem.

    If it’s something more

    #2: Usually I don’t like it, but if it’s useful, go for it.

  4. Michael Stum says:

    I vote for #1. After all, using your Template is optional, so it’s like using any Third Party Tool which also may or may not make changes. I do not know if it’s possible displaying a little "Do not show this dialog again"-Dialog that warns the Developer before, but again: Those Templates are optional addons*, so they should better be as good as possible.

    *Or will they be official part of ASP.net MVC 2.0?

  5. Dave says:

    I vote for 1.  Just make sure it works with files under source-control properly.  Don’t want it falling over when it tries to modify read-only files.

  6. Erik says:

    #1 – fine by me, as long as the changes are documented. I’ll echo the request for a notification dialog asking permission.

  7. I don’t mind a bit as long as "stuff" works 🙂

  8. beltbucklestud says:

    That is right. As long as it’s working properly, it doesn’t matter even if it would take sometime. 🙂

  9. Ken says:

    If it’s optional then I agree with #1.  On the line before or after the modified line can you add a comment prefixed with a keyword to indicate it was modified.  Something along the lines of

    //T4MOD: Previous line was modified by MVC T4 Template.

    Interesting idea though.

  10. George says:

    #1.  Warn/Notify the user, sure, but the user should have everything in source control, right?  

  11. KevDog says:

    Maybe a preview of changes or a big fat "I’m about to mess with your code, is that okay?" dialog before the code runs.

    Or else I’ll sue you.

    My demand? A really good chocolate chip cookie.

  12. D. Lambert says:

    I’d vote for #1 with some prior notification (even if just by documentation) that the code may be changed.  If you’re under source code control, you’ll see the changes distinctly, anyway, right?

  13. John Sheehan says:

    Make it an option. At the top of the T4 template add a bool constant for ALLOW_CODE_CHANGES set to false by default.

  14. Felipe Fujiy says:

    My vote is for #2, but in this case, I think is not necessary.

  15. Robert Slaney says:

    #1.  I’ve used your MVC TT as inspiration for a raft of codegen scenarios, include generating WCF proxies from our service interface assembly by creating new class files in the proxy project

  16. Daniel says:

    I think this needs to consider source control providers that use the checkin/checkout model.  They make the files read-only.  A better option might be to have a macro or add-in that can be run separately to "Refactor Controllers to Support Dave’s t4 template".

  17. The key is it has to be ONLY "making classes partial and methods virtual"

    Anything else and you will want to conduct this poll again.

  18. Johnny says:

    I’m ok if it asks for permission.

  19. Hi David,

    Nice work.Can you please put it on CodePlex?

  20. AdamR says:

    Nice work, thanks!

    My view: #1. Go for it.

  21. codingoutloud says:

    This is a whole different ballgame than inserting gen’d code or modifying the logic, so considering what we get in return, this seems fine to me; bring it on.

    A subtle message that the changes were made would ease the some of the paranoia. I think an "are you sure" dialog box is too intrusive, but it would be okay if it had a "don’t ask me anymore" checkbox. (There might be some more targetted visual indicator possible for VS 2010 with the editor open for customization.)

  22. It’s strange that you’re so angsty about it 🙂 You’ve got a great idea, and you think that it will be useful – why not go straight for it and implement it? There may be haters, and there will always be, and a poll won’t change that 🙂 It’s your art! Don’t be influenced by anyone…

  23. Jamal Hansen says:

    #2 Smart features in IDEs / templates are great until you find that you are fighting against them for some reason.  As long as there is a way to turn the feature off, if necessary, it’s great.

  24. W.Meints says:

    I’m fine with templates that modify my code. As long as it is documented and doesn’t do stuff that isn’t documented.

  25. Brannon says:

    #1 for partial.  #2 for virtual!

    Adding an option to the T4 template to disable the code modifications would be great.  Default it to enabled, but let people who don’t like it turn it off.

  26. Sruly Taber says:

    I vote #2

    I don’t Like it but if it makes my life that much easier I will go along with it.

    BTW thanks for the great template

  27. Jpg says:

    i vote for 1.

    There is already loads of magical stuff to MVC that you dont see – where only altering old code right?

    New code – having the template installed and generating…=> good.

  28. Rafael da Silva says:

    #1, as long as I know who/what changed it.

  29. Mike says:

    Hmm, why even ask? NEVER change my code… NEVER NEVER NEVER. Thanks!

  30. Tad says:

    Hi, I am interested if it would work on Mono platform??

  31. Tical says:

    #2 + I hope u can make it have the courtesy to tell the dev (w/t)hat things have changed. Partial is harmless by runtime but virtual makes a fundamental semantic change. You may want to modify the template to respect members with modifiers like final or abstract and notify the dev of those instances as well.

  32. shawn says:

    I’m somewhere between #1 and #2.  If there were a way to do it without modifying the source that would be preferable, but if developers are aware of the changes then it never hurts to make life easier. 🙂

  33. Why not make those helpers encapsulate our controllers?

    The T4MVC_AccountController doesn’t really need to inherit from the real AccountController doesn’t it?

    As long as all methods on T4MVC_AccountController are there which shouldn’t be a problem to generate.

    So keeping this in mind it’s #2.5 since i hate magic strings even more than I hate having to change my code to support tools.

  34. Oh and btw majority is usually wrong so making a poll was a very bad idea.

    Now i suppose we are stuck with inheritance over composition.

  35. David: favoring refactoring support (tool) over design is imho not the way to go in the same way as naming your methods to order well in intelisense wouldn’t you agree?

  36. David Ebbo says:

    Michal: I guess it comes down to weighing the pros and cons of the different approaches, and I see how you could make that point. Ideally, the language would be rich enough to not need this T4 template in the first place. Of course, it does come close with Expressions, but the resulting syntax is fairly nasty.

  37. mmm if developers are aware than it should be ok

  38. Andrei Rinea says:

    Modify my code all you want. After all the JIT modifies our code everytime : it makes native code out of C#/IL.

    I haven’t heard of someone suing the JIT/CLR team for that..

  39. my view would be 1, I would personally go for that!

Skip to main content