如何编写引用dotnet标准2.0项目的roslyn分析器

bra*_*ing 4 .net c# xunit roslyn .net-standard-2.0

我从以下项目的Roslyn分析器测试用例中得到以下错误

https://github.com/Weingartner/Migrations.Json.Net

预期集合为空,但找到{Test0.cs(5,2):错误CS0012:类型'属性'在未引用的程序集中定义.您必须添加对程序集'netstandard,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'.}的引用.

DiagnosticVerifier.Helper.cs中的当前元数据引用是

private static readonly MetadataReference CorlibReference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
private static readonly MetadataReference SystemReference = MetadataReference.CreateFromFile(typeof(System.Uri).Assembly.Location);
private static readonly MetadataReference SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location);
private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location);
private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location);
private static readonly MetadataReference SystemRuntimeReference = MetadataReference.CreateFromFile(Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").Location);
private static readonly MetadataReference MigrationReference = MetadataReference.CreateFromFile(typeof(MigratableAttribute).Assembly.Location);
private static readonly MetadataReference SerializationReference = MetadataReference.CreateFromFile(typeof(DataMemberAttribute).Assembly.Location);
private static readonly MetadataReference JsonNetReference = MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.JsonConvert).Assembly.Location);
Run Code Online (Sandbox Code Playgroud)

其中一个参考

private static readonly MetadataReference MigrationReference =
    MetadataReference
      .CreateFromFile(typeof(MigratableAttribute).Assembly.Location);
Run Code Online (Sandbox Code Playgroud)

是指子项目Weingartner.Json.Migration

在此输入图像描述

这个项目是一个dotnetstandard 2.0项目

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <RootNamespace>Weingartner.Json.Migration</RootNamespace>
    <AssemblyName>Weingartner.Json.Migration</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Weingartner.Json.Migration.Common_\Weingartner.Json.Migration.Common.csproj" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

但是,当我运行分析器测试用例时,我得到运行时错误,我应该参考netstandard

预期集合为空,但找到{Test0.cs(5,2):错误CS0012:类型'属性'在未引用的程序集中定义.您必须添加对程序集'netstandard,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = cc7b13ffcd2ddd51'.}的引用.在FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)FluentAssertions.Execution.AssertionScope.FailWith(String message,Object [] args)FluentAssertions.Execution.GivenSelector 1.FailWith(String message, Object[] args) at FluentAssertions.Collections.CollectionAssertions2.BeEmpty(String because,Object [] becauseArgs)at TestHelper.位于TestHelper.DiagnosticVerifier的TestHelper.DiagnosticVerifier.GetSortedDiagnostics(String [] sources,String language,DiagnosticAnalyzer analyzer)的TestHelper.DiagnosticVerifier.GetDocuments(String [] sources,String language)中的DiagnosticVerifier.CreateProject(String [] sources,String language).在Weingartner.Jigration.Migration.Roslyn.Spec.DataContractAnalyzerSpec.ShouldCreateDiagnosticIfMigratableTypeDoesntHaveDataContractAttributeSet()的TestHelper.DiagnosticVerifier.VerifyCSharpDiagnostic(String source,DiagnosticResult [] expected)上的VerifyDiagnostics(String [] sources,String language,DiagnosticAnalyzer analyzer,DiagnosticResult [] expected)

我的猜测是我在创建项目时遗漏了一些东西.我看不到一个API来指定我所针对的框架的哪个版本,但API非常大,所以也许我错过了一些东西.

    private static Project CreateProject(string[] sources, string language = LanguageNames.CSharp)
    {
        string fileNamePrefix = DefaultFilePathPrefix;
        string fileExt = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt;

        var projectId = ProjectId.CreateNewId(debugName: TestProjectName);

        var solution = new AdhocWorkspace()
            .CurrentSolution
            .AddProject(projectId, TestProjectName, TestProjectName, language)
            .AddMetadataReference(projectId, CorlibReference)
            .AddMetadataReference(projectId, SystemReference)
            .AddMetadataReference(projectId, SystemCoreReference)
            .AddMetadataReference(projectId, CSharpSymbolsReference)
            .AddMetadataReference(projectId, CodeAnalysisReference)
            .AddMetadataReference(projectId, SystemRuntimeReference)
            .AddMetadataReference(projectId, MigrationReference)
            .AddMetadataReference(projectId, SerializationReference)
            .AddMetadataReference(projectId, JsonNetReference);
        var compilationOptions = solution
            .GetProject(projectId)
            .CompilationOptions
            .WithOutputKind(OutputKind.DynamicallyLinkedLibrary);
        solution = solution
            .WithProjectCompilationOptions(projectId, compilationOptions);

        int count = 0;
        foreach (var source in sources)
        {
            var newFileName = fileNamePrefix + count + "." + fileExt;
            var documentId = DocumentId.CreateNewId(projectId, debugName: newFileName);
            solution = solution.AddDocument(documentId, newFileName, SourceText.From(source));
            count++;
        }
        var project = solution.GetProject(projectId);
        var diangostics = project.GetCompilationAsync().Result.GetDiagnostics();
        diangostics.Should().BeEmpty();
        return project;
    }
Run Code Online (Sandbox Code Playgroud)

bra*_*ing 12

事实证明,答案与错误信息一样明显.只是对netstandard的引用.

diff --git a/Weingartner.Json.Migration.Roslyn.Spec/Helpers/DiagnosticVerifier.Helper.cs b/Weingartner.Json.Migration.Roslyn.Spec/Helpers/DiagnosticVerifier.Helper.cs
index da3b933..ba6cc7c 100644
--- a/Weingartner.Json.Migration.Roslyn.Spec/Helpers/DiagnosticVerifier.Helper.cs
+++ b/Weingartner.Json.Migration.Roslyn.Spec/Helpers/DiagnosticVerifier.Helper.cs
@@ -28,6 +28,7 @@ namespace TestHelper
         private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location);
         private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location);
         private static readonly MetadataReference SystemRuntimeReference = MetadataReference.CreateFromFile(Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").Location);
+        private static readonly MetadataReference NetStandard = MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0").Location);
         private static readonly MetadataReference MigrationReference = MetadataReference.CreateFromFile(typeof(MigratableAttribute).Assembly.Location);
         private static readonly MetadataReference SerializationReference = MetadataReference.CreateFromFile(typeof(DataMemberAttribute).Assembly.Location);
         private static readonly MetadataReference JsonNetReference = MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.JsonConvert).Assembly.Location);
@@ -169,6 +170,7 @@ namespace TestHelper
                 .AddMetadataReference(projectId, SystemRuntimeReference)
                 .AddMetadataReference(projectId, MigrationReference)
                 .AddMetadataReference(projectId, SerializationReference)
+                .AddMetadataReference(projectId, NetStandard)
                 .AddMetadataReference(projectId, JsonNetReference);
             var compilationOptions = solution
                 .GetProject(projectId)
Run Code Online (Sandbox Code Playgroud)