Here's one. I have a bunch of T4s in one project / solution. This is a framework with support code and T4 templates.
In a different solution, I want to use this framework, but have the support classes / T4s remain in the original solution.
In the new solution I link to the support code and T4s (add existing / link). Now in the new solution I have a T4 which needs to include the linked T4. It has something like this:
<## template language="C#" debug="false" hostspecific="true"#>
<## include file="..\Models\DALContextGenerator.tt"#>
<## output extension=".cs"#><#
Generate("..\Models\Model1.edmx");
>
In this case, DALContextGenerator.tt is in this solution, but is linked to the real DALContextGenerator.tt in a different solution. WHen I run the T4 I get an error ("Failed to resolve include text"). If I reference the physical location it is fine.
Any ideas?
Thanks
Ray
As far as I know, the T4 engine uses the template file as a root and is unaware of the Visual Studio Solution and Solution items. If you're using a Visual Studio link to a file somewhere else this information is only stored in the project file. The T4 engine looks up the include-path relative to the T4 file. That's why referencing the Visual Studio Link relatively fails. But referencing the include file either with its absolute path or a relative one pointing to the physical file succeeds.
Here are some ideas how to address your problem, but there is no "smooth" solution I can think of:
Use a hard link between the original include file and a file located next to the template file (command line: mklink /H source target)
if you are using a source control system (like svn) you can work with external directories without duplicating your originals
Have a (meta-)T4 template that generates the actual T4 template with the proper paths based on the information you get from Env.DTE Visual Studio Model
Old but relevant question, I think the same as this other thread, where I posted a reply, using expansions $(ProjectDir) and $(SolutionDir): https://stackoverflow.com/a/42785952/1948625
Related
In visual studio there are 2 types of text transformation templates file extensions .T4 vs .TT
I would like to know their differences and which one I should use when I want extend to build Views Controllers and Models, when I read a schema off a DB
I also want to know if .includes can be reused in both.
There is no difference. Back around 2008 this feature was treated as if it were an add-in (even though it ended up being built into VS directly). Microsoft called it the "Text Template Transformation Toolkit," hence the .T4 extension. Common usage shortened that to "text templates" yielding the .TT extension and this appears to have become the standard extension.
Transformation files are just code, they can use any feature of the language you choose. For example, in C# templates I regularly reference .NET assemblies as follows:
<## import namespace="System.Text" #>
I can't seem to find a way to make T4 templates in VS 2015 RTM, in an ASP.NET 5 (vNext) project.
I even installed the T4 toolbox for Visual Studio 2015 extension, but the tt templates are not transformed.
The property Custom Tool doesn't appear in the tt file properties, neither can't I find the 'Run Custom Tool' command.
Update
The reason I want the T4 templates, is the introduction of the config.json file, and the pluggable configuration system, which is an awesome thing, but with the price of not having the setting properties strongly-typed.
I've read this article that explains how to achive this, but there is still no generation. Since I have a pretty complex configuration structure, I thought about making a T4 template that will generate an AppSettings file. Any ideas on that are obviously welcome too.
The ASP.Net 5 (vnext) project is a completely new animal and technically still in beta, its not scheduled for RC til November 2015. Also it's attempting to be completely cross platform so initially the team favored using razor templates instead of T4 for scaffolding. They had no plans to support T4 (or any single file generators) at all until an out cry from the community made them change their mind. According to that thread they will support it but have given no dates. They do seem to have made progress, back in January when I was testing my T4 extension I had issues with the project file(now in json format) not supporting custom properties but as of the release on 7/20/2015 it seems to work now. The engine for running T4 inside of visual studio 2015 is still there so you can use it if you like from other project types. You can create a console app and have it store the T4 files but generate them in the vnext project. If you want a cleaner solution you can also try out my extension T4 Awesome, it gives you a way to organize and call your templates via right click menus.
I've found that I can still use the MSBuild targets that ship with the Modeling SDK for Microsoft Visual Studio 2015 when building an ASP.NET 5 project with ASP.NET 5 RC1.
I got there by modifying the directions from
MSDN - Code Generation in a Build Process.
Add the *.tt and the output files (*.cs in my case) to the project folder structure.
Unload and edit the project's *.xproj file.
Add the following Import element after the Microsoft.DNX.targets import:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" />
Add an ItemGroup element similar to the following (I added this immediately before the import statements):
<ItemGroup>
<Content Include="MyTemplate.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>MyTemplate.cs</LastGenOutput>
</Content>
</ItemGroup>
Optionally, you can add elements to the Globals PropertyGroup element to control the transformation task:
<TransformOnBuild>true</TransformOnBuild>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
Reload the project's *.xproj and build normally.
The templates I'm using are pretty simple, so there might be limitations of this approach that I'm missing out on.
If you watch Julie Lerman's pluralsight video: http://www.pluralsight.com/courses/entity-framework-7-looking-ahead she addresses this. There are no plans as of now to remove the T4 templates in upcoming versions of Visual Studio but they didn't make it in for the release. You code always run the reverse engineer tool on your database and go with a code first approach and switch back later (though I don't know why you would in my opinion) but that would be a work around until there is more information on the T4 templates in current VS versions.
I was able to get my T4 file to work properly when I run it within visual studio but it errors out when automating it to happen during the build process automatically.
The problem is that in order to reference an assembly that is in the same solution but another project I added this line:
<## assembly name="$(SolutionDir)\My.Core\bin\Debug\My.Core.dll" #>
In order to just run a single T4 template on build, I created a post build-event with the following command:
"%PROGRAMFILES(x86)%\Common Files\microsoft shared\TextTemplating\10.0\TextTransform.exe" $(ProjectDir)\Features\Admin\app\Abilities.tt
But since the host is not the IDE environment at this point it throws an error because it is treating the $(SolutionDir) a literally so it can't find the assembly reference for My.Core.dll.
So my question is, how can I reference that assembly within the T4 template so that it works with the build process I have and ideally still be able to right click and run the transformation manually, but that isn't as important.
I should also note that using the full path is not an option since there are multiple developers and the source code will be living in potentially different directories on each developer machine.
I am automating my project using T4 templates. For this, I have to write some repeated code using T4 template and some hand written code which should not be overwritten by the T4 template. I would like to add the generated code file as the dependent file of the handwritten file. I am following convention of class1.cs for handwritten file and class1.generated.cs for generated file. How can I add this generated file in the project as dependent file of class1.cs?
To do this programmatically you'll have to modify the .csproj file directly. Refer to this question for details:
In Visual Studio (2008) is there a way to have a custom dependent file on another custom file?
If you want to do this via the IDE then use the VSCommonds Add-in for Visual Studio 2010.
It's been a while since I last used T4 and this is probably a silly question...
Is it possible to reference an arbitrary assembly from a template?
Example:
I have a class that I'd like to use in Project X
Project X.Test references X and contains the .tt file
I assume the following should work
<## assembly name="X" #>
But I get the following error on save:
Compiling transformation: Metadata
file 'X' could not be found
What am I doing wrong?
(In case anyone's interested: I'm trying to automatically generate a particular type of tests based on some metadata that I get from X)
Update: it looks like VS2010 has broken the assembly resolution behavior that I was expecting. From Link:
T4's assembly set is completely
separated from the containing
project's assembly set to avoid
picking up the wrong assemblies when a
project targets previous framework
versions. Project assemblies are no
longer used to resolve template
assembly directives.
Are there any workarounds, besides using absolute paths?
You can use VS macro variables such as $(SolutionDir) in your reference as of VS2010
e.g.
<## assembly name="$(SolutionDir)\Project1\bin\debug\Foo.dll" #>
You can also check here on SO: Can't reference an assembly in a T4 template
#GarethJ gives a good answer but for all the methods of referencing an assembly from a T4 template try this: T4 Template error - Assembly Directive cannot locate referenced assembly in Visual Studio 2010 project.
And if you like the VS Macro solution then you can find 'em all here: Macros for Build Commands and Properties