在T4转型期间“无法从主机获得DTE”

时间:2012-04-05 16:41:29

标签: visual-studio entity-framework templates t4

我使用Visual Studio SDK和Visual Studio 2010建模和可视化SDK安装的解决方案,关注此帖Get Visual Studio to run a T4 Template on every build

...但是我得到了一个我无法解决的错误:

  

错误2运行转换:System.ArgumentNullException:值不能为null。    参数名称:无法从主机获取DTE       在Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.VsEntityFrameworkTemplateFileManager..ctor(Object textTemplating)       在Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.Create(Object textTransformation)       在Microsoft.VisualStudio.TextTemplatingE035559D977B9B9858AB2036321BC47D.GeneratedTextTransformation.TransformText()       在Microsoft.VisualStudio.TextTemplating.TransformationRunner.RunTransformation(TemplateProcessingSession session,String source,ITextTemplatingEngineHost host,String& result)。 Line = 0,Column = 0 ApmWeb.Web.Client

按照我的剧本的第一部分......

<#@ 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);

更新 我发现问题在于这一点上的“EF.Utility.CS.ttinclude”......

dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
        if (dte == null)
        {
            throw new ArgumentNullException("Could not obtain DTE from host");
        }

我的想法是,在VS主机外运行转换时无法获取DTE对象。发生此错误,例如在Team Build中运行转换时(MSBuild主机不“知道”DTE对象)。实际上它使用来自VS的“运行自定义工具”,但配置autamatic T4构建,正如我在上一篇文章中所说,它不起作用。

那怎么解决?这是EF.Utility.CS.ttinclude的错误吗?

更新 使用DTE删除与VS的交互(在EF.Utility.CS.ttinclude中定义PREPROCESSED_TEMPLATE)一切正常,但我放松了将生成的文件添加到我的项目的能力......还有其他方法可以使用吗?

1 个答案:

答案 0 :(得分:0)

正如您所发现的那样,在构建时进行转换时,您无法访问DTE。 处理项目中未出现的生成代码的一种方法是将其包含在通配符中,例如:

      

只要您使用标准输出命名约定,这应该会给您一个合理的体验。您还可以使用构建目标将生成的输出重定向到特定文件夹,然后使用更简单的通配符将所有内容包含在文件夹中。

您必须注意IDE中的手动调整将删除此通配符,并将其替换为其评估的时间点结果。