[MonoDevelop] T4 add-in

Michael Hutchinson m.j.hutchinson at gmail.com
Wed Sep 30 14:09:47 EDT 2009


On Wed, Sep 30, 2009 at 3:38 AM, Brett Michael <klunket at sent.com> wrote:
> I'm interested to extend the current T4 functionality in MonoDevelop.
> However, upon searching for examples of making add-ins, etc, I noticed
> a couple of plugins where people had used less than optimal APIs, etc,
> because they didn't know other ones existed.

Hopefully this is easier to avoid now we have the API overview for
basic APIs http://monodevelop.com/Developers/Articles/API_Overview

> So that I can research what it would take further, can someone point
> me in the correct place that I would hook to do the following:
>
> * Add T4 as a new file type (with a post-selection screen like the MVC
> View one to select a master page)

Adding new file templates is pretty straightforward. Just look at some
*.xft.xml files and how they're registered in the .addin.xml files.

The post-selection screen isn't so easy, as it involved defining a
custom template type. I'd recommend waiting for after MD 2.2, because
we want to overhaul the file/project templating system and make it
much easier to have more complex scenarios like that. What do you need
it for in this case?

> * Run T4 on any .tt files, whenever they are saved (or on a pre-build
> event, before code is compiled).

To hook into the build, implement and register a
ProjectServiceExtension and override one of its virtual methods.
Here's an explanation of how it works:
http://foodformonkeys.blogspot.com/2007/04/horizontal-extensions.html
See the ASP.NET addin for an example, the VerifyCodeBehindBuildStep,
which ensures codebehind files are updated before building.

If you want to run the T4 files on save, it probably makes sense to
have the T4EditorExtension subscribe to the document save event. Don't
forget to unsubscribe when the extension's disposed. This would also
be the place to look at for code completion (I stubbed some of it
out).

Regarding running the files, it's probably best to keep it simple and
just invoke the bundled TextTransform.exe file on them, or use a very
basic templating host. I'm not sure I'd want to commit to a
MD-specific template host API yes, especially one that gives access to
the MD API yet. Take a look at
MonoDevelop.AspNet.Mvc.Gui.FolderCommandHandler.AddView for an example
of running a template, though for more generic running of templates
the functionality could be implemented as a public API on the
TextTemplatingService, which could keep a re-usable templating
AppDomain around, recycle it every 10 templates or so, or close it if
hasn't been used for a minute.

After the files are written, you'd want to notify MD that the files
have changed using FileService.NotifyFileChanged, so that things like
the C# parser can pick up the changes. Alternatively you could use the
MonoDevelop.DesignerSupport.OpenDocumentFileProvider to get a file
handle that would also allow you to write into files that are open in
the text editor, and would automatically perform this notification for
you.

> * Add a context-menu option to .tt files that runs T4 on them.

Define a command and register it on the project pad's file content
menu (/MonoDevelop/Ide/ContextMenu/ProjectPad) with an ProjectFile
ItemType condition. The command handler can operate on the
IdeApp.ProjectOperations.CurrentSelectedItem (so the command can be
keybound and invoked without the context menu). Additionally it should
set enabled/visible to false when the CurrentSelectedItem is not a tt
file.

See e.g. MonoDevelop.AspNet.Deployment.ProjectDeployHandler for a
simple command handler. See also the sample at
http://monodevelop.com/Developers/Articles/Creating_a_Simple_Add-in

> * Create a "code-behind" style file hanging under any .tt file that
> has been generated. I.e. if test.tt has test.cs as output, it would
> appear hanging beneath test.tt

When running the tt file, add the output file to the project and set
its DependsOn property to the parent tt file. You could query the
ProjectDomService for the T4ParsedDocument in order to inspect the
output directives and determine the output filename.

> Let me know if any of that doesn't make sense. Superficially it seems
> like a reasonably easy plugin that might let me give back to my
> favourite IDE.

All make sense to me. Thanks for looking at it!

IMO it would make sense to do this directly in the existing T4 addin
rather than creating a new addin. I might even be able to sneak it
into 2.2...

-- 
Michael Hutchinson
http://mjhutchinson.com


More information about the Monodevelop-list mailing list