I follow this post Get Visual Studio to run a T4 Template on every build, using the solution with Visual Studio SDK and Visual Studio 2010 Modeling and Visualization SDK installation.
...BUT I get an error that I cannot solve:
Error 2 Running transformation: System.ArgumentNullException: Value cannot be null. Parameter name: Could not obtain DTE from host at Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.VsEntityFrameworkTemplateFileManager..ctor(Object textTemplating) at Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.Create(Object textTransformation) at Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.TransformText() at Microsoft.VisualStudio.TextTemplating.TransformationRunner.RunTransformation(TemplateProcessingSession session, String source, ITextTemplatingEngineHost host, String& result). Line=0, Column=0 ApmWeb.Web.Client
Following the first part of my script...
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ output extension=".cs"#><#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);
string inputFile = @"../../ApmWeb.Infrastructure.Data/Model/ApmWebModel.edmx";
MetadataWorkspace metadataWorkspace = null;
bool allMetadataLoaded =loader.TryLoadAllMetadata(inputFile, out metadataWorkspace);
EdmItemCollection ItemCollection =
(EdmItemCollection)metadataWorkspace.GetItemCollection(DataSpace.CSpace);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager =
EntityFrameworkTemplateFileManager.Create(this);
UPDATE I found that the problem is into "EF.Utility.CS.ttinclude" in this point...
dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
if (dte == null)
{
throw new ArgumentNullException("Could not obtain DTE from host");
}
My idea is that you can’t get the DTE object when running the transformation outside the VS Host. This error occurs, for example when running the transformation within a Team Build (the MSBuild Host does not “know” the DTE object). In effect it works using "run custom tool" from VS but configuring the autamatic T4 build as I told in previous post, it doesn't work.
So how can solve? Is it a bug of EF.Utility.CS.ttinclude?
UPDATE Removing interaction with VS using DTE (define PREPROCESSED_TEMPLATE in EF.Utility.CS.ttinclude) all works, but I loose e.g. capability to add generated file to my project... Is there an other way to put working it?
As you've discovered, you're not going to have access to the DTE when transforming at build time. One approach to dealing with the generated code not appearing in your project is to include it with a wildcard e.g.
As long as you use a standard output naming convention this should give you a reasonable experience. You can also use the build targets to redirect the generated output to a specific folder and then use a simpler wildcard to include everything in the folder.
You do have to watch out that manual tweaking in the IDE will remove this wildcard and replace it with a point in time outcome of its evaluation.