How can I make a Roslyn Analyzer project a transitive dependency?
Asked Answered
B

1

10

I have a library that relies on a source generator to work correctly. In the MyLibrary.csproj, I reference the generator like so.

<ItemGroup>
  <ProjectReference 
        Include="..\MyLibrary.Generators\MyLibrary.Generators.csproj" 
        PrivateAssets="contentfiles;build"
        ReferenceOutputAssembly="false"
        OutputItemType="analyzer"/>
</ItemGroup>

I need this analyzer reference to be transitive, i.e. projects that reference MyLibrary should get the MyLibrary.Generators analyzer transitively.

A simple reference like so does not seem to reference the analyzer, only MyLibrary

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

I want to stress that I am not looking for MyLibrary.Generators to be consumed as a regular assembly reference, but as a Roslyn Analyzer so my source generator can run as intended during compile time.

Boondocks answered 23/2, 2021 at 7:17 Comment(7)
What is stopping you from adding the project reference manually? Note that if you are looking to ship the binary output from MyLibrary.csproj, you should do so in a nuget package, which can include the generator library.Wendt
I have an MSBuild SDK set up so presumably consumers of my library will be able to consume the generator as an analyzer reference that way, but I was hoping for a stronger guarantee via transitivity.Boondocks
Have you been able to find any solution to this?Guttapercha
No, I haven't, unfortunately.Boondocks
I don't have an exact answer for you, but I've had some luck using the Microsoft.Build.NoTargets SDK to hand craft nuget packages for project references without causing an assembly reference. I think part of the issue you're having might be related to the ReferenceOutputAssembly="false" which may be interfering with the default pack target dependency generation.Betti
Did you manage to find a solution for this problem? Currently having the exact same problem and I want to avoid some trickery with nuget packages.Eppie
I have not been able to find a good solution for this. Currently I'm requiring all consumers of my framework to use a custom MSBuild SDK that references the analyzer project. See hereBoondocks
O
2

I have received an answer to this question on GitHub.

It is sufficient for the library project to have the following reference to the generator project:

  <ItemGroup>
    <!-- Package the generator in the analyzer directory of the nuget package -->
    <None Remove="$(OutputPath)/$(AssemblyName).Generator.dll" />
    <None Include="$(OutputPath)/$(AssemblyName).Generator.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
  </ItemGroup>

(I am not sure if the Remove line does anything. It might be unnecessary.)

When the library is consumed as a NuGet package, the generator is automatically included as an analyzer, i.e. the analyzer reference is transitive.

However, when the library is consumed through a project reference (such as in the library's own unit test project), we need the following:

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

The examples in the original post all handle project references. From what I have gathered, a transitive project reference to an analyzer seems impossible, unfortunately.

Oringas answered 4/10, 2021 at 7:58 Comment(1)
Drawback: If the Generator project depends on other packages, they are not referenced in the resulting package.Cubital

© 2022 - 2025 — McMap. All rights reserved.