Базовый пример генератора исходного кода C# NET 5.0 не генерирует вывод

Я копирую все как можно точнее из примера веб-сайта 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.

Поскольку копирование всего этого раздражает, вот ссылка для загрузки, если вы ленивы: Ссылка для загрузки 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!");
        }
    }
}

2 ответа

Изменять

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

к

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

Приношу свои извинения, предыдущий ответ был совершенно неверным. Кроме того, у меня слишком мало репутации для комментариев, поэтому я отправляю это.

Я пытался сделать что-то подобное с 3 проектами и получал аналогичную ошибку (хотя у меня было много других проблем). Мне пришлось добавить ссылку на исходный генератор в нижнем проекте (Консоль в вашем случае). Также я добавил Debugger.Launch() что помогло разобраться в конкретных проблемах.

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