BuilderGenerator icon indicating copy to clipboard operation
BuilderGenerator copied to clipboard

CS0436 warning when importing builders into another project.

Open bcheidemann opened this issue 2 years ago • 1 comments

When importing builders generated with BuilderGenerator into another project, the following warnings are produced:

/home/user/repos/example/Tests/BuilderGenerator/BuilderGenerator.BuilderGenerator/BuilderBaseClass.cs(26,16): warning CS0436: The type 'Builder<T>' in 'BuilderGenerator/BuilderGenerator.BuilderGenerator/BuilderBaseClass.cs' conflicts with the imported type 'Builder<T>' in 'SharedEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Using the type defined in 'BuilderGenerator/BuilderGenerator.BuilderGenerator/BuilderBaseClass.cs'. [/home/user/repos/example/Tests/Tests.csproj]

BuilderGenerator is being used to generate builders in a project shared by multiple other projects (including Tests). This has the following .csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- Disabled because BuilderGenerator produces code missing the #nullable annotation -->
    <NoWarn>$(NoWarn);CS8669</NoWarn>
  </PropertyGroup>

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

  <ItemGroup>
    <PackageReference Include="Bogus" Version="34.0.2" />
    <PackageReference Include="BuilderGenerator" Version="2.3.0" />
  </ItemGroup>

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

One of the applications using it (Tests) has the following .csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Bogus" Version="34.0.2" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
    <PackageReference Include="Moq" Version="4.20.69" />
    <PackageReference Include="xunit" Version="2.4.2" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="3.2.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <None Update="testsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\MyWebApi\MyWebApi.csproj" />
    <ProjectReference Include="..\Libs\SharedEntities\SharedEntities.csproj" />
  </ItemGroup>
</Project>

I unfortunately don't have time right now to submit a minimal reproduction, so I understand if this issue gets closed. I'll try and remember to come back to this when I have more time.

bcheidemann avatar Dec 09 '23 15:12 bcheidemann

First: It doesn't appear that I'm getting notifications from GitHub on these issues, or it got lost in the shuffle/wall of notifications from work. Sorry about that.

Second: I'll have to reproduce this, I guess. That sounds messy. It seems like you shouldn't be seeing the one in the package itself, though, and that's probably where the problem lies. The whole reason I have to inject that file into the project referencing the library is because an assembly isn't supposed to be able to be used as an analyzer AND as a library at the same time.

MelGrubb avatar Dec 31 '23 17:12 MelGrubb

After doing a lot of research about source generators for a course I've been developing, I have found that this is a not-too-uncommon problem, although it's usually the attribute class that causes the problem. The issue is normally that two different projects use the same generator. Both then have a definition of the marker attribute class for the generators. When a third project references both of the others, we now have a duplicate definition. There are a few solutions to this.

  1. Alter the name of the marker attribute for each project so they don't collide. I'm not even going to consider this because it's objectively awful
  2. Define the attribute in a separate project which is then required by the generator project. This would be something like BuilderGenerator.Core or BuilderGenerator.Common.
  3. Define the attribute in a separate project (like BuilderGenerator.Core), but package it directly into the generator package as a library. Andrew Lock referenced this in a blog series on source generators if you're interested in the gory details. https://andrewlock.net/creating-a-source-generator-part-8-solving-the-source-generator-marker-attribute-problem-part2/

MelGrubb avatar Feb 02 '25 00:02 MelGrubb