Почему рефлексия по собственным типам не работает в шаблоне T4? - PullRequest
0 голосов
/ 07 октября 2018

У меня есть приложение .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, сгенерированный этим шаблоном, содержит «String».

Однако теперь у меня есть класс Foo в Foo.cs.в той же папке, что и мой шаблон:

namespace Bar
{
    public class Foo
    {
    }
}

Теперь я хочу использовать Foo вместо строки, поэтому я просто изменяю строку

var myType = typeof(string);

на

var myType = typeof(Foo);

и сохраните шаблон.Теперь я получаю сообщение об ошибке:

Выполнение преобразования: System.IO.FileNotFoundException: не удалось загрузить файл или сборку 'System.Runtime, версия = 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?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Я получил это, работая с обходным путем.

Попробуйте поместить это 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>
0 голосов
/ 04 ноября 2018

Механизм T4 использует .NetFramework, поэтому он имеет те же проблемы со ссылкой на DLL-файл .net, что и любое другое приложение .Net Framework.T4 работает в отдельном домене приложения и не наследует ссылки вашего основного проекта .net.

typeof (строка) работает, потому что это часть .Net Framework.Ваш тип "Foo" зависит от ссылок на сборки .Net Core.Я не уверен, что можно загрузить сборки .Net Core в T4 без переноса вашей сборки на .Net Standard.

Вы можете попробовать Загрузка сборки в контексте только для отражения , но обычно я вижу людей, использующих T4, через доступ к информации о классах, которые они имеют в своем проекте, через EnvDTE, Roslyn или Visual Studio SDK.Если нет другой причины, по которой вы хотите отразить свою базовую сборку .Net от T4, у вас не будет проблем с получением информации о типе через EnvDTE!

...