Невозможно скомпилировать простой динамический код после миграции на.netstandard 2.0 (CodeDom генерирует исключение System.PlatformNotSupportedException)

Попытка скомпилировать этот пример кода:

var c = new CSharpCodeProvider();
var cp = new CompilerParameters();
var className = $"CodeEvaler_{Guid.NewGuid().ToString("N")}";
// doesn't work with or without netstandard reference
var netstandard = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
cp.ReferencedAssemblies.Add(netstandard.Location);
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;

var sb = new StringBuilder("");

sb.Append("namespace Jobs.Dynamic{ \n");
sb.Append($"public class {className} {{\n");
sb.Append($"public object RunSnippetCode()\n{{\n");
sb.Append("\nreturn null;\n");
sb.Append("\n}\n");
sb.Append("}");
sb.Append("}");

CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());

До миграции на.netstandard 2.0 все было нормально

Простой класс должен быть сгенерирован, и он работает, если просто скопировать код и запустить его в Visual Studio. Класс с одним методом, который возвращает ноль. Теперь метод CompileAssemblyFromSource выдает

System.PlatformNotSupportedException: операция не поддерживается на этой платформе. в Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(параметры CompilerParameters, String[] fileNames) в Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(параметры CompilerParameters.Co.Connet.Co. т е р (IEnumerable1 referencedAssemblies, IEnumerable1 использование, String methodArgs, String codeSnippet) в CnetContent.Jobs.Core.JobBase.EvalRunCondition(String& error)

Я обновил System.CodeDom, и эта библиотека поддерживает.netstandard 2.0, но этот код по-прежнему не работает. Не удалось найти ни одного случая с похожими проблемами. Есть идеи? Заранее спасибо!

2 ответа

У меня была та же проблема с.NetCore 2, но с большим проектом CodeDOM. Мое решение, которое я сейчас строю, - это сгенерировать исходный код из CodeDom и передать его Roslyn. (Как было упомянуто в комментарии к Roslyn, но было опубликовано только решение.NET Framwork)

Вот хороший пример, как использовать Roslyn - просто добавьте

Microsoft.CodeAnalysis.CSharp пакет NuGet и пакет System.Runtime.Loader NuGet

и затем используйте код здесь (или просто следуйте примеру): https://github.com/joelmartinez/dotnet-core-roslyn-sample/blob/master/Program.cs

В моем случае я переносил проект из .NET Framework 4.7.2 к .NET Standard 2.0. В этом проекте у меня есть код для создания сборки во время выполнения с помощью CSharpCodeProvider. Мог скомпилировать проект, но затем во время выполнения мой код выдал исключение при создании сборки из Dom. У меня такая ошибка:

      CS0012: The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

Как следствие, сборка не была создана во время выполнения.

Чтобы исправить это, я добавил .netstandard для компилятора как сборка, на которую указывает ссылка:

      var compilerParameters = new CompilerParameters();
var netstandard = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
compilerParameters.ReferencedAssemblies.Add(netstandard.Location);

Это помогло мне.

Другие вопросы по тегам