我正在尝试创建一个可重用的 .NET Standard 2.0 库,该库使用 Roslyn 在运行时将代码动态编译为内存中的程序集。这个动态创建的程序集包含从作为库一部分的基类派生的类。我通过引用该库的应用程序中的反射来实例化它们。项目结构如下所示:
假设我的 netstandard2.0 库中有以下类型:
namespace MyLibrary
{
public abstract class BaseClass
{
public abstract int CalculateSomething();
}
}
然后,我在 .NET Core 2.2 项目中创建以下单元测试:
namespace NetCore2_2.Tests
{
public static class RoslynTests
{
[Fact]
public static void CompileDynamicallyAndInvoke()
{
// Create syntax tree with simple class
var syntaxTree = CSharpSyntaxTree.ParseText(@"
using System;
using MyLibrary;
namespace Foo
{
public sealed class Bar : BaseClass
{
public override int CalculateSomething()
{
return (int) Math.Sqrt(42);
}
}
}");
在此测试中,我首先解析源自 netstandard2.0 库中的BaseClass 的一段 C# 代码。这段代码还引用了System.Math。然后,我创建一个 C# 编译对象,其中包含对(.NET Core 2.2 的)核心库和我的库的引用。该编译对象将 DLL 发送到内存流。如果编译失败,测试将失败并出现包含所有诊断信息的异常。
此单元测试失败并显示以下错误消息:
(7,31):错误CS0012:类型“对象”;在未引用的程序集中定义。您必须添加对程序集“netstandard,Version=2.0.0.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”的引用。
(11,26):错误CS0012:类型“对象”;在未引用的程序集中定义。您必须添加对程序集“netstandard,Version=2.0.0.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”的引用。
我有以下问题:
这是否不起作用,因为 Roslyn NuGet 包在 .NET Standard 2.0 项目中被引用,因此总是尝试编译为 netstandard2.0 目标框架 Moniker? 我怀疑netstandard2.0 对 System.Object
有不同的定义,转发到目标平台的实际实现。而且我的编译单元中并没有引用这个转发定义。
有办法更改目标框架吗?我查看了CSharpCompilationOptions
和EmitOptions
,但无法 39;没有找到任何可以让我改变目标框架的东西。
我是否需要使用其他 Roslyn NuGet 软件包,例如 Microsoft.Net.Compilers.Toolset? 我尝试避免这种情况,因为实际上想使用默认编译器而不是 NuGet 包中的编译器。
PIPIONE
相关分类