5

我正在尽可能地从Microsoft 网站示例中复制所有内容,但没有生成任何内容。我创建了一个 MCVE 来尝试找出发生以下错误的原因:

Warning CS8034  
Unable to load Analyzer assembly C:\Users\me\source\repos\SourceGenTest\SourceGenerators\bin\Debug\netstandard2.0\SourceGenerators.dll: 
Could not find file 'C:\Users\me\source\repos\SourceGenTest\SourceGenerators\bin\Debug\netstandard2.0\SourceGenerators.dll'.
SourceGenLibrary        1   Active

我已经检查了提供的路径,并且SourceGenerators.dll存在。这个错误对我来说毫无意义。

注意:在我提供的 MCVE 中,显然没有构建警告。不知道为什么,但是源生成器仍然没有输出。

我的目标是有一个像这样的工作流程:

SourceGenerators (class library)
    is consumed by
        SourceGenLibrary (class library)
            is consumed by
                SourceGenConsole (Console project)

因此,我想要一个分析器在类库中生成定义,该类库将在许多项目之间共享。上述工作流程将其简化为一个依赖于一个库的项目,该库依赖于源生成器,以保持 MCVE-as-possible。

因为复制所有这些东西很烦人,如果你很懒,这里有一个上传链接:下载链接 MCVE(据说发布后一周到期,但来源如下)。

相关资料:

$ dotnet --version
5.0.201

$ dotnet --list-sdks
5.0.103 [C:\Program Files\dotnet\sdk]
5.0.201 [C:\Program Files\dotnet\sdk]

这些是源文件及其包含的内容。

/SourceGenTest.sln

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31112.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenLibrary", "SourceGenLibrary\SourceGenLibrary.csproj", "{8702B80A-ACA3-4546-BBE8-A9FEE686A758}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerators", "SourceGenerators\SourceGenerators.csproj", "{D693D3B2-F981-4D6D-AC97-B8C636E8C5C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenConsole", "SourceGenConsole\SourceGenConsole.csproj", "{3730848C-847C-4DF9-A0B3-5ADB5FE9D1E0}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {8702B80A-ACA3-4546-BBE8-A9FEE686A758}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {8702B80A-ACA3-4546-BBE8-A9FEE686A758}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {8702B80A-ACA3-4546-BBE8-A9FEE686A758}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {8702B80A-ACA3-4546-BBE8-A9FEE686A758}.Release|Any CPU.Build.0 = Release|Any CPU
        {D693D3B2-F981-4D6D-AC97-B8C636E8C5C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {D693D3B2-F981-4D6D-AC97-B8C636E8C5C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {D693D3B2-F981-4D6D-AC97-B8C636E8C5C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {D693D3B2-F981-4D6D-AC97-B8C636E8C5C0}.Release|Any CPU.Build.0 = Release|Any CPU
        {3730848C-847C-4DF9-A0B3-5ADB5FE9D1E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {3730848C-847C-4DF9-A0B3-5ADB5FE9D1E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {3730848C-847C-4DF9-A0B3-5ADB5FE9D1E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {3730848C-847C-4DF9-A0B3-5ADB5FE9D1E0}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {A3752997-47E1-4086-87C8-1583B5E0EDF1}
    EndGlobalSection
EndGlobal

/SourceGenerators/SourceGenerators.csproj

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" />
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" />
  </ItemGroup>

</Project>

/SourceGenerators/Class1.cs

using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

namespace SourceGeneratorSamples
{
    [Generator]
    public class HelloWorldGenerator : ISourceGenerator
    {
        public void Execute(GeneratorExecutionContext context)
        {
            // begin creating the source we'll inject into the users compilation
            var sourceBuilder = new StringBuilder(@"
            using System;
            namespace HelloWorldGenerated
            {
                public static class HelloWorld
                {
                    public static void SayHello() 
                    {
                        Console.WriteLine(""Hello from generated code!"");
                        Console.WriteLine(""The following syntax trees existed in the compilation that created this program:"");
            ");

            // using the context, get a list of syntax trees in the users compilation
            var syntaxTrees = context.Compilation.SyntaxTrees;

            // add the filepath of each tree to the class we're building
            foreach (SyntaxTree tree in syntaxTrees)
            {
                sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");");
            }

            // finish creating the source to inject
            sourceBuilder.Append(@"
                    }
                }
            }");

            // inject the created source into the users compilation
            context.AddSource("helloWorldGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }

        public void Initialize(GeneratorInitializationContext context)
        {
        }
    }
}

/SourceGenLibrary/SourceGenLibrary.csproj

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

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>preview</LangVersion>
    <AssemblyName>SourceGenLibrary</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\SourceGenerators\SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
  </ItemGroup>

</Project>

/SourceGenLibrary/Class1.cs

using System;

namespace SourceGenTest
{
    public class Class1
    {
        public static void Func()
        {
            //HelloWorldGenerator.HelloWorld.SayHello();
        }
    }
}

/SourceGenConsole/SourceGenConsole.csproj

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\SourceGenLibrary\SourceGenLibrary.csproj" />
  </ItemGroup>

</Project>

/SourceGenConsole/Program.cs

using System;

namespace SourceGenConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
4

1 回答 1

0

抱歉,之前的回答完全错误。另外,我的代表太低无法发表评论,所以我提交了这个。

我试图对 3 个项目做类似的事情并遇到类似的错误(尽管我也遇到了许多其他问题)。我必须在底部项目(在您的情况下为控制台)中添加对源生成器的引用。我还添加了一个Debugger.Launch()有助于深入研究特定问题的内容。

于 2021-05-20T00:46:45.690 回答