我有一个.NET Core 2.1 ASP.NET MVC应用程序,其中有一个设计时T4模板,我想用它来生成一些代码。当前,它看起来像这样:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(SolutionDir)\Bar\bin\Debug\netcoreapp2.1\Bar.dll" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="Bar" #>
<#@ output extension=".txt" #>
<#
var myType = typeof(string);
var myName = y.Name;
Write(myName);
#>
这有效:该模板生成的.txt文件包含“字符串”。
但是,现在我在Foo.cs中有一个与模板相同的文件夹中的Foo类:
namespace Bar
{
public class Foo
{
}
}
现在我要使用Foo而不是字符串,所以我只需要更改行
var myType = typeof(string);
到
var myType = typeof(Foo);
并保存模板。现在我得到一个错误:
正在运行的转换:System.IO.FileNotFoundException:无法 加载文件或程序集'System.Runtime,Version = 4.2.1.0, 文化=中性,PublicKeyToken = b03f5f7f11d50a3a'或其中之一 依赖性。
堆栈跟踪如下:
File name: 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at Microsoft.VisualStudio.TextTemplating9418B77BB4C607966DB4F31F6C9D57D97D9892B08324572567CEAC228ECCD2BE3839F9E2A0AE0ECA2D5DD0CCC161A70762C40A6D67A8DC505F3E88E86A36C7CE.GeneratedTextTransformation.TransformText()
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at CallSite.Target(Closure , CallSite , Object )
at Microsoft.VisualStudio.TextTemplating.TransformationRunner.PerformTransformation()
为什么会引发此错误?为什么反射对于内置字符串类型有效,但是以某种方式依赖于.NET Framework 4.2.1作为我自己的.NET Core 2.1类型?
答案 0 :(得分:1)
T4引擎使用.NetFramework,因此与其他任何.Net Framework应用程序一样,引用.net核心dll的问题相同。 T4在单独的应用程序域中运行,并且不会继承.net核心项目的引用。
typeof(string)之所以有效,是因为它是.Net Framework的一部分。您的“ Foo”类型取决于对.Net Core程序集的引用。我不确定是否可以将.Net Core程序集加载到T4中,而无需将程序集移植到.Net Standard。
您可以尝试Loading The Assembly in a Reflection-Only Context,但是我看到人们使用T4的通常方法是通过EnvDTE,Roslyn或Visual Studio SDK访问他们在项目中拥有的类的信息。除非有其他原因要从T4反映到.Net核心程序集中,否则通过EnvDTE检索类型信息将毫无问题!
答案 1 :(得分:1)
我得到了解决方法。
尝试将此bindingRedirect放在C:\Users\<user>\AppData\Local\Microsoft\VisualStudio\15.0_29f8d23a\devenv.exe.config
-> <configuration>
-> <runtime>
中的<assemblyBinding>
里面,所有其他的bindingRedirect都在哪里
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>