Hi I'm trying to write a SourceGenerator that uses the Humanizer package (This package is only needed while generating code and should not be added as a reference in the project that uses the SourceGenerator)
So I have the following files:
TestSourceGenerator\TestSourceGenerator.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IsRoslynComponent>true</IsRoslynComponent>
<ImplicitUsings>enable</ImplicitUsings>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput</TargetsForTfmSpecificContentInPackage>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.1.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" PrivateAssets="all" />
</ItemGroup>
<Target Name="_AddAnalyzersToOutput">
<ItemGroup>
<TfmSpecificPackageFile Include="$(OutputPath)\$(AssemblyName).dll" PackagePath="analyzers/dotnet/cs" Pack="true" Visible="false" />
<TfmSpecificPackageFile Include="$(OutputPath)\Humanizer.dll" PackagePath="analyzers/dotnet/cs" Pack="true" Visible="false" />
</ItemGroup>
</Target>
</Project>
TestSourceGenerator\SourceGenerator.cs
using System.Text;
using Humanizer;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
namespace TestSourceGenerator;
[Generator]
public class SourceGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
var builder = new StringBuilder(1024);
builder.AppendLine(@$"using System;
namespace {context.Compilation.Assembly.ContainingNamespace?.Name ?? context.Compilation.Assembly.Name};
static class AssemblyInformation {{
public static string Name = ""{context.Compilation.AssemblyName}"";
public static string HumanizedName = ""{context.Compilation.AssemblyName.Humanize()}"";
}}
");
context.AddSource("AssemblyInformation.cs", SourceText.From(builder.ToString(), Encoding.UTF8));
}
public void Initialize(GeneratorInitializationContext context)
{
}
}
TestSourceGenerator\Properties\launchSettings.json
{
"profiles": {
"Profile 1": {
"commandName": "DebugRoslynComponent",
"targetProject": "..\\ConsoleApp1\\ConsoleApp1.csproj"
}
}
}
ConsoleApp1\ConsoleApp1.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TestSourceGenerator\TestSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
</ItemGroup>
</Project>
ConsoleApp1\Program.cs
Console.WriteLine("Name: " + AssemblyInformation.Name);
Console.WriteLine("Name: " + AssemblyInformation.HumanizedName);
Every thing works as expected when I debug the SourceGenerator using Profile 1.
But if I try to compile ConsoleApp1 it complains that it can't find the Humanizer even when its there
Generator 'SourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'FileNotFoundException' with message 'Could not load file or assembly 'Humanizer, Version=2.14.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e' or one of its dependencies. The system cannot find the file specified.'
What am I missing? I have verified that Humanizer is part of the nuget file when I pack the SourceGenerator.
A copy of the code can be found here: https://github.com/AnderssonPeter/TestSourceGenerator
PrivateAssetsattributes differTestSourceGenerator.csprojI have Humanizer.Core withPrivateAssets="all"just like they have in the cookbook? But just for the fun I removed all PrivateAssets="all" cleaned my solution, restarted vs and ran again, same error :(