Базовый пример генератора исходного кода 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()
что помогло разобраться в конкретных проблемах.