T4模板VS2010获取宿主程序集

6
我希望能够获取T4模板所在项目的程序集引用。我知道可以使用例如Host.ResolveAssemblyReference("$(ProjectDir)")来获取项目路径,然后可能会添加bin\\debug\\{projectName}.dll,因为我的程序集名称是以项目名称命名的,但这并不总是正确的,并且我正在创建一个可重用的模板,因此我需要dll的路径或最好是Assembly实例。

我还找到了如何获取Project引用的方法,如这里中的GetProjectContainingT4File方法所述,但那样做之后呢?

是否有方法可以获取它?

顺便说一句,我需要该引用来访问特定类型并从中生成一些代码。


一种可能性是找到 .csproj 文件,解析它并提取构建输出路径。这是一个 XML 文件。 - Just another metaprogrammer
嗯...是的,我可能可以,好主意。我会尝试的。 - Kosta
2个回答

13

以下简单的代码适用于我(VS 2013):

var path = this.Host.ResolveAssemblyReference("$(TargetPath)");
var asm = Assembly.LoadFrom(path);

同时您也可以在项目发布后构建步骤编辑器中找到$(...)属性。


谢谢!我苦恼了几天,直到发现了你的极其简单的代码! - Avrohom Yisroel

10

好的,我成功地获取了需要引用的汇编代码。@FuleSnabel给了我一个提示,尽管我没有使用他的建议。

这是我的T4模板的一部分:

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".output" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ Assembly Name="System.Xml.Linq.dll" #>
<#@ Assembly Name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
<#@ Assembly Name="EnvDTE" #>
<#@ Assembly Name="EnvDTE80" #>
<#@ Assembly Name="VSLangProj" #>

<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Reflection" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ include file="T4Toolbox.tt" #>
<#
    Project prj = GetProject();
    string fileName = "$(ProjectDir)bin\\debug\\" + prj.Properties.Item("OutputFileName").Value;
    string path = Host.ResolveAssemblyReference(fileName);
    Assembly asm = Assembly.LoadFrom(path);

    // ....
#> 

// generated code goes here

<#+
    Project GetProject()
    {
        var serviceProvider = Host as IServiceProvider;
        if (serviceProvider == null) 
        {
            throw new Exception("Visual Studio host not found!");
        }

        DTE dte = serviceProvider.GetService(typeof(SDTE)) as DTE;

        if (dte == null) 
        {
            throw new Exception("Visual Studio host not found!");
        }

        ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
        if (projectItem.Document == null) {
            projectItem.Open(Constants.vsViewKindCode);
        }

        return projectItem.ContainingProject;
    }
 #>

因此,为了找到汇编的正确路径,我必须在GetProject() 方法中获取对项目的引用,然后使用该项目的属性OutputFileNameprj.Properties.Item("OutputFileName").Value。由于我无法找到任何有关项目具有哪些属性的信息,因此我使用枚举和循环来检查Properties集合,然后找到我需要的内容。以下是循环代码:

<#
// ....
foreach(Property prop in prj.Properties)
{
    #>
    <#= prop.Name #>
    <#
}
// ....
#>

我希望这能帮助到某人。


1
谢谢,这让我在路的起点上跨过了一个小坎。 - TeaDrivenDev

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