T4模板:在宿主程序集中导入命名空间

6

大家好,

我有一个T4模板。

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core" #>
<#@ Assembly Name="System.Windows.Forms" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="MyLibrarysRootNameSpace.SomeNamespace" #>
/*Rest of template follows*/

我正在尝试导入最后一行,以便我可以轻松地在其他项目中重用此模板,但似乎我漏掉了某些内容。我想做的事情是否可能?如果是,该怎么做呢?


System.CoreSystem.Windows.Forms程序集都不包含命名空间MyLibrarysRootNameSpace.SomeNamespace,因此很明显导入失败了。你到底想要实现什么? - dtb
MyLibrarysRootNameSpace.SomeNamespace 是指包含在我的代码中的类定义的命名空间。它是主机项目的一部分,不属于任何系统命名空间(这就是为什么我将其以 My 开头) 。 - William
2个回答

11

Import语句只是添加了一个using语句,并没有引用程序集。T4的引用程序集集合与托管模板的项目完全独立。

如果你想使用托管项目的程序集,那么你需要使用程序集指令来实现。类似以下内容:

<#@ assembly name="$(TargetPath)" #>

请注意,这里引入了一个构建循环,所以在生成DLL之前,项目需要手动干预构建过程。因此,请确保只会生成可选的或者始终可以使用以前检入版本的部分代码。


我会将这个标记为答案,尽管正如你所说它会导致构建循环。事实证明,我认为我需要进行类型比较的东西并不是那么重要。 - William
“Import” 仅仅是添加一个 using 语句。明确一下,它导入了一个命名空间;它不会将 using 语句写入输出文件。(这可能是你的意思。) - Dave Cousineau
它向中间代码添加了一个using语句,该语句被编译和执行以生成输出文件。 - GarethJ

1
如果我理解你的问题正确:
复制并粘贴前两个片段从那里,以获取包含T4的项目的EnvDTE对象模型。
<#@ assembly name="EnvDte" #>
<#
    var visualStudio = ( this.Host as IServiceProvider )
        .GetService( typeof( EnvDTE.DTE ) ) as EnvDTE.DTE;
    var project = visualStudio.Solution
        .FindProjectItem( this.Host.TemplateFile )
        .ContainingProject as EnvDTE.Project;
#>

然后,使用那里的方法来获取该项目的默认命名空间:

// project is of type: EnvDTE.Project
string strDefaultNamespace = project.Properties.Item( "DefaultNamespace" )
    .Value.ToString();

然后,根据您的需要使用strDefaultNamespace值。

这将获取命名空间,但程序集仍未被引用。 - GarethJ
你可以使用System.IO.StreamWriter类来编写单行ImportDefaultNamespace.tt文本文件,然后使用<#@ include指令来包含该文件。 然而,我认为这样做没有任何价值。在项目中复制粘贴源代码文件通常不是一个好的实践方式(共享程序集通常更好),但你还必须编辑你已经复制粘贴的源代码文件中的命名空间? - Soonts
如果您没有共享的代码/接口,那么您将无法重用T4,因为它不会编译。自动命名空间导入除非命名空间包含您从T4源代码调用的类,否则无济于事。 或者,如果在T4中您只对数据类型进行反射而不是直接调用它们,则不需要导入任何命名空间。 - Soonts
http://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration/ - William
如果你使用CodeModel来读取项目中的代码而不是反射,那么Colin的方法非常好,你可以构建一些非常好的解决方案。 - GarethJ
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接