在T4模板中加载NuGet程序集

9
我需要在包含 Visual Studio T4 模板的项目所引用的程序集中引用一种类型(Type)。但是,被引用的程序集是通过 NuGet 包进行安装的。随着 Nuget 引用的更新,NuGet 会将其放置在解决方案的 packages 文件夹中,因此路径也会发生变化。例如,假设我的 NuGet 包是:
Facade.Contract.1.0.1-alpha
那么,从我的项目到它的相对路径是:
..\packages\Facade.Contract.1.0.1-alpha\lib\net4\Facade.Contract.dll
如果预发布版本升级为 beta 版,则该路径将更改。当包发布时,路径也会更改。每次路径更改时,*.tt 文件中的程序集行也会过时:
<#@ assembly name="..\packages\Facade.Contract.1.0.1-alpha\lib\net4\Facade.Contract.dll" #>
我认为没有直接使用程序集指令完成这个任务的方法;然而,我开放接受一些疯狂的想法。我可以把程序集自己加载进当前或下属或仅反射的 AppDomain 中吗?
我想我可以,但我不确定如何使用 T4 逻辑动态地发现项目引用中所引用程序集的路径。
有什么想法吗?

1
你是如何执行T4模板的?它们是在Visual Studio中运行还是在使用msbuild进行构建时运行的? - Frank
它在Visual Studio内运行(与我在编辑中所说的不同... 我将尽快更正)。因此,我应该可以访问整个DTE。 - Trinition
我正在使用VSLangProj做一些进展,以发现引用路径,受到这篇文章的启发:http://t4-editor.tangible-engineering.com/blog/add-references-to-visual-studio-project-from-t4-template.html - Trinition
1
很好的问题,在我看来T4中有一个很大的遗漏。请在UserVoice上投票:https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/15837976-allow-loading-nuget-assemblies-from-t4-files。 - Ohad Schneider
2个回答

4
我找到了一种解决方案,使用VSLangProject,正如这篇文章所建议的:http://t4-editor.tangible-engineering.com/blog/add-references-to-visual-studio-project-from-t4-template.html 给定一个字符串serviceContractReferenceAssembly以标识我的包含项目中引用程序集的名称,以及serviceContractReferenceType 以标识该程序集中的类型,下面的方法可以起作用:
    var templateItem = dte.Solution.FindProjectItem(this.Host.TemplateFile);
    var project = templateItem.ContainingProject;
    var vsProject = project.Object as VSLangProj.VSProject;
    foreach(var referenceObj in vsProject.References)
    {
        var reference = (VSLangProj.Reference)referenceObj;
        if(reference.Name != serviceContractReferenceAssembly) continue;
        var serviceContractAssembly = Assembly.LoadFile(reference.Path);
        var serviceContractType = serviceContractAssembly.GetType(serviceContractReferenceType);
        // Do something with it here
    }

2
Nuget团队提供了一个扩展,可以让你对解决方案/项目中的软件包进行一些控制。因此,如果你能够控制环境并确保每个人都安装了此项服务,那么在T4执行期间,你可能能够搜索已安装的软件包,并动态加载它们。由于这些Nuget程序集已经编译过而且不是你解决方案/项目的一部分,我认为使用标准的Assembly.Load应该可以工作,但需要进行测试。

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