Udostępnij za pośrednictwem


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

  • Anonymous
    June 24, 2009
    My vote is for #2.  I don't like the idea, but if it's really useful I might put up with it.

  • Anonymous
    June 24, 2009
    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 :D

  • Anonymous
    June 24, 2009
    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.

  • Anonymous
    June 24, 2009
    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?

  • Anonymous
    June 24, 2009
    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.

  • Anonymous
    June 24, 2009
    #1 - fine by me, as long as the changes are documented. I'll echo the request for a notification dialog asking permission.

  • Anonymous
    June 24, 2009
    I don't mind a bit as long as "stuff" works :)

  • Anonymous
    June 24, 2009
    That is right. As long as it's working properly, it doesn't matter even if it would take sometime. :)

  • Anonymous
    June 24, 2009
    The comment has been removed

  • Anonymous
    June 25, 2009
    #1.  Warn/Notify the user, sure, but the user should have everything in source control, right?  

  • Anonymous
    June 25, 2009
    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.

  • Anonymous
    June 25, 2009
    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?

  • Anonymous
    June 25, 2009
    Make it an option. At the top of the T4 template add a bool constant for ALLOW_CODE_CHANGES set to false by default.

  • Anonymous
    June 25, 2009
    My vote is for #2, but in this case, I think is not necessary.

  • Anonymous
    June 25, 2009
    #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

  • Anonymous
    June 25, 2009
    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".

  • Anonymous
    June 25, 2009
    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.

  • Anonymous
    June 25, 2009
    I'm ok if it asks for permission.

  • Anonymous
    June 25, 2009
    Hi David, Nice work.Can you please put it on CodePlex?

  • Anonymous
    June 25, 2009
    Nice work, thanks! My view: #1. Go for it.

  • Anonymous
    June 25, 2009
    The comment has been removed

  • Anonymous
    June 25, 2009
    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...

  • Anonymous
    June 25, 2009
    #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.

  • Anonymous
    June 25, 2009
    I'm fine with templates that modify my code. As long as it is documented and doesn't do stuff that isn't documented.

  • Anonymous
    June 25, 2009
    #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.

  • Anonymous
    June 25, 2009
    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

  • Anonymous
    June 25, 2009
    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.

  • Anonymous
    June 25, 2009
    #1, as long as I know who/what changed it.

  • Anonymous
    June 25, 2009
    Hmm, why even ask? NEVER change my code... NEVER NEVER NEVER. Thanks!

  • Anonymous
    June 26, 2009
    Hi, I am interested if it would work on Mono platform??

  • Anonymous
    June 26, 2009
    #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.

  • Anonymous
    June 26, 2009
    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. :)

  • Anonymous
    July 10, 2009
    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.

  • Anonymous
    July 10, 2009
    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.

  • Anonymous
    July 10, 2009
    Mihal, the benefit of extending the controller class is to get refactoring support (see http://blogs.msdn.com/davidebb/archive/2009/06/26/the-mvc-t4-template-is-now-up-on-codeplex-and-it-does-change-your-code-a-bit.aspx)

  • Anonymous
    July 13, 2009
    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?

  • Anonymous
    July 14, 2009
    The comment has been removed

  • Anonymous
    August 11, 2009
    mmm if developers are aware than it should be ok

  • Anonymous
    August 16, 2009
    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..

  • Anonymous
    August 28, 2009
    my view would be 1, I would personally go for that!