Skip to content

InternalsVisibleTo from two other projects leads to not being able to use PolySharp #50

Closed

Description

@cremor

Description

If one project references two other projects that both have InternalsVisibleTo to the first project defined, the first project can't use C# features that should be enabled by PolySharp.

Reproduction Steps

  1. Create a new solution with 3 projects using an older .NET version.
  2. Set <LangVersion>11.0</LangVersion> for all projects.
  3. Add PolySharp to all projects.
  4. Try to use a C# 11 feature, e.g. required properties, in all projects. See that it works as expected.
  5. Add a project reference from two projects to the third one.
  6. Add <ItemGroup><InternalsVisibleTo Include="ThirdProjectName" /></ItemGroup> to the referenced projects.

Expected Behavior

Should be able to compile the code.

Actual Behavior

I get compile errors about missing compiler required members.

System info

This section should contain useful info such as:

  • PolySharp NuGet version 1.10.0
  • Operating system version Windows 10 22H2
  • Visual Studio version, or .NET SDK/runtime version VS 17.4.4, SDK 7.0.102, runtime 7.0.2

Additional context

It looks like the compiler error is missleading. The members are not missing, they are there multiple times (so the compiler sees the internal types from both referenced projects). If only one referenced project with InternalsVisibleTo exists then no error happens.

It looks like PolySharp also sees the internal types of the other projects and doesn't generate any additional types. (It only generates the TypeForwards.)
But I can actually fix the problem and compile my code when I manually add the required compiler types. Then the compiler doesn't error any more, even though it should then actually see each type 3 times.
So maybe the fix for this would be to still generate the required types if the source generator only finds an internal type from another assembly in the current project?

In my actual solution I don't add PolySharp to each project individually but instead use Global Package References. But it seems like this doesn't change anything for this problem.

Activity

  1. Shane32 commented on Jan 18, 2023

    @Shane32
  2. cremor commented on Jan 18, 2023

    @cremor
    Author

    Thanks, but I don't think there is a way to apply this to my situation, right? I don't need to exclude PolySharp from running in one project like in the linked issue. Instead I'd need it to run even though it thinks it doesn't need to.

  3. Shane32 commented on Jan 18, 2023

    @Shane32

    I’m not sure. It sounded like the identical issue to mine so I posted the link. I had 2 viable workarounds which both worked for me, one being to ensure the TFM for all projects matched, and the other being to exclude PolySharp from the third project. If that’s viable you could do so with a ProjectReference Remove in the csproj while maintaining global package references.

  4. cremor commented on Jan 18, 2023

    @cremor
    Author

    I only have a single target framework (net48) and need PolySharp in all projects.

  5. cremor commented on Jan 19, 2023

    @cremor
    Author

    Without knowing anything how PolySharp works internally I see three possible solutions:

    • Change PolySharp to generate types which are only available in the current project as an internal type from a different assembly.
      I think this would be the best solution, unless it has some unexpected negative consequence.
    • Change PolySharp to generate types which are only available in the current project as an internal type from at least two different assemblies.
      This change would have a smaller impact, but is very specific for my problem. There might be other situations that I'm not thinking of right now which then would not be fixed.
    • Add a new setting to PolySharp that forces it to generate types even if they are available in the current project (similar to PolySharpIncludeGeneratedTypes).
      This would allow a fix for my problem without changing anything for existing users. But it would also require other users that have the problem to find that setting and known to enable it to fix this (complicated) problem.
  6. Applesauce314 commented on Mar 24, 2023

    @Applesauce314

    I had the exact same issue [InternalsVisibleTo] in multiple referenced projects, giving the same issue as above.
    My solution was as follows:

    1. Create an additional project (I called it PolyfillProvider),
    2. Have this project target the TFMs used by any project in my solution (in my case net6.0;net472;netstandard2.0)
    3. Add Polysharp to this project
    4. Made the polysharp polyfills public <PolySharpUsePublicAccessibilityForGeneratedTypes>true</PolySharpUsePublicAccessibilityForGeneratedTypes>
    5. add this project as a reference to all the other projects.

    Each project gets only the polyfills needed for the TFM.
    You would not get per project customization, but you get the benefits of PolySharp.

    Edit: If public accessibility is a problem for you see alternate steps in the comment below

  7. m-ringler commented on Apr 3, 2023

    @m-ringler

    This issue is preventing me from switching from the IsExternalInit and IndexRange nuget packages to PolySharp (which I would
    otherwise prefer as a one-stop-solution). @cremor's suggested solutions would all be acceptable for me.

    @Applesauce314's public generated types workaround has the side effect of making the generated types visible to consumers of your code. If two libraries use that workaround you cannot (easily) use both of them at the same time. So that does not work for me.

  8. Applesauce314 commented on Apr 3, 2023

    @Applesauce314

    @Applesauce314's public generated types workaround has the side effect of making the generated types visible to consumers of your code. If two libraries use that workaround you cannot (easily) use both of them at the same time. So that does not work for me.

    @m-ringler I checked if removing <PolySharpUsePublicAccessibilityForGeneratedTypes>true</PolySharpUsePublicAccessibilityForGeneratedTypes> and instead adding [assembly: InternalsVisibleTo("assembly.Name")] for each project that needs the polyfills, and it worked, I think that would satisfy the need to not have the polyfills public, I did not test having multiple polyfill projects that do this, but I would expect it to work.

  9. JoelDavidLang commented on May 11, 2023

    @JoelDavidLang

    Is there an ideal solution to this issue yet?

    I just encountered it when creating a .NET 6.0 unit test project for a library that is targeting .NET Standard 2.0 while using PolySharp. Because the library has internals visible to the unit test project, I get this error.

    It seems I can work around it by excluding IsExternalInit from generation in the unit test project. I want PolySharp to handle this by default though, so this error doesn't happen.

  10. Applesauce314 commented on May 11, 2023

    @Applesauce314

    Is there an ideal solution to this issue yet?

    I just encountered it when creating a .NET 6.0 unit test project for a library that is targeting .NET Standard 2.0 while using PolySharp. Because the library has internals visible to the unit test project, I get this error.

    It seems I can work around it by excluding IsExternalInit from generation in the unit test project. I want PolySharp to handle this by default though, so this error doesn't happen.

    I don't know if it is "ideal", but I have been using the separate project with the default
    internal accessibilty and [assembly:InternalsVisibleTo()] for each project that uses it for a month now.

    The only problem I have had so far was when I added a new project and forgot to add it to the list, spent a few minutes looking for a broken config before I remembered.

  11. martinsuchan commented on Jun 9, 2023

    @martinsuchan

    Hi, this problem is currently blocking us from using PolySharp in our larger solution.
    Out of available options I think having a MSBuild flag for "Always generating polyfills" is the best option here?

  12. lilith commented on Jan 23, 2024

    @lilith

    I would concur. And this happens a lot with unit test projects. I publish a lot (77+) of NuGet packages that multi-target net8.0;netstandard2.0;net6.0. If Always generate polyfills works well, perhaps it should be the default at least for unit test projects?

  13. dropsonic commented on Apr 29, 2024

    @dropsonic

    Bump. This issue also blocks PolySharp usage in our solution.

  14. MarkKharitonov commented on Aug 13, 2025

    @MarkKharitonov

    So there is unmerged PR #127 which claims to solve this issue. For some reason it is not merged.
    I created another PR (#130) which solves it in a different way by providing the always generate polyfills flag.

    Is it possible to merge one of these PRs? I have a big enterprise application with multiple solutions and hundreds of projects which we want to migrate to .NET, but that would take time. In the meantime we want to unlock the modern language features using PolySharp, but we cannot because of this issue. And the workarounds do not scale very well.

    @Sergio0694 - would you be able to merge either of the two PRs, please?

  15. dropsonic commented on Aug 13, 2025

    @dropsonic

    I support @MarkKharitonov on this. We also have a huge enterprise-grade product running on the .NET Framework, and we desperately need this fixed.

  16. 19 remaining items

  17. jviau commented on Sep 12, 2025

    @jviau

    @MarkKharitonov net472 won't have those expected types. Loading your commit, I can see the PolySharp generator isn't generating those types for that project either (unsure why).

    Image

    The fix here is to investigate why PolySharp isn't generating all types for PolySharp.InternalsVisibleTo.Tests. Once that is resolved the InternalsVisibleToAttribute will start working as expected.

  18. MarkKharitonov commented on Sep 12, 2025

    @MarkKharitonov

    There is an explicit check in the PolySharp code that prevents the polyfills from being generated if it deems they are already available -

    if (compilation.HasAccessibleTypeWithMetadataName(name))

    I guess they are available, because of the InternalsVisibleTo, which makes ALL the internal types visible, including the polyfills. However, when 2 or more projects have InternalsVisibleTo to the same project, that project is in a predicament:

    1. It sees the poly fill types as available and so it does not generate them.
    2. The analyzer refuses to consider them, because of the conflict since exactly the same poly fills come from multiple different projects.

    And that is the root of the problem. My rejected workaround (PR #130) allows to circumvent the item (1) if an explicit flag is given. This way poly fills are generated even if they are available from another project.

  19. jviau commented on Sep 12, 2025

    @jviau

    Got it. I agree that some way is needed to ensure the types are generated here. Is adding that msbuild property the only way? Or does HasAccessibleTypeWithMetadataName need to be fixed here? Because that type isn't actually "accessible".

  20. MarkKharitonov commented on Sep 12, 2025

    @MarkKharitonov

    I am not claiming my workaround is perfect, but it works and it is simple. True, there is an ugly element to it, because it may produce the warning CS0436, which is quite expected.

    And I wish we had a proper fix. In the meantime, my company published the spinoff package - https://www.nuget.org/packages/PolySharp.TemporaryIssue50Workaround/1.0.0-beta. It is just PolySharp 1.15.0 + my PR. We gave it this name to communicate that it is strictly temporary until this issue is properly resolved at which point we will happily delist the package. We could have published it locally to our internal artifactory, but figured that others may benefit from this temporary workaround.

  21. jviau commented on Sep 15, 2025

    @jviau

    @Sergio0694 I noticed there aren't any generator unit tests set up. Or I am just missing them. Having those would go a long way in diagnosing why HasAccessibleTypeWithMetadataName returns true here, and next steps in ensuring it doesn't when the embedded attribute is used.

  22. Windows10CE commented on Oct 15, 2025

    @Windows10CE
    Contributor

    My PR #134 should fix this issue the "correct" way, by detecting if the members that are candidates for already existing have EmbeddedAttribute on them and are not in the same assembly. It goes on top of the existing PR #127. If any of you are still experiencing this and would like a fix other than @MarkKharitonov's, you should be able to build that branch in the meantime.

  23. markk-df commented on Oct 15, 2025

    @markk-df

    I can confirm. The test projects I added compile cleanly with your fix and fail without it.
    Here is the branch containing the 2 PRs and my test projects - https://github.com/dayforce-hcm/PolySharp/commits/dev/embedded-types

  24. markk-df commented on Nov 6, 2025

    @markk-df

    @Sergio0694 - is there any chance you could update your PR branch with the change from @Windows10CE? You can add test projects showing off the issue from my branch - https://github.com/dayforce-hcm/PolySharp/commits/dev/embedded-types/

    This is your PR branch onto which I cherry-picked changes from @Windows10CE and my test projects. It works well.

    Is it possible to update your PR branch, merge it and finally close this issue? It does not have to be you, anyone with your permission can do it.

    Thank you very much,

  25. ns88ns commented on Apr 1, 2026

    @ns88ns

    @Sergio0694 - Seems the solution is still problematic.

    Although it resolves #50 and #103, it introduces another problem:
    I tested the dev/embedded-types and what I found:

    The same setup: one unit-test project consumes internals from several other library projects in the same solution.

    All projects use PolySharp, the unit-test project also uses it (otherwise, what's the sense).
    All projects are configured with:

    • PolySharpUsePublicAccessibilityForGeneratedTypes: false
    • PolySharpIncludeRuntimeSupportedAttributes: true
    • PolySharpUseEmbeddedAttributeForGeneratedTypes: true

    The library projects have the [assembly: InternalsVisibleTo()]

    Polyfills are working well in the lib projects themselves, but aren't generated in the unit-test project. Instead, it produces:

    • CS0122: 'DynamicallyAccessedMemberTypes' is inaccessible due to its protection level (once per per dependency);

    In addition, if any polyfills are used in the unit-test project:

    • CS0246: The type or namespace name '...' could not be found (are you missing a using directive or an assembly reference?)
    • CS0518: Predefined type '...' is not defined or imported
    • CS0656: Missing compiler required member '.....ctor'

    Please, find the minimal repro solution attached.
    _test_02.zip

    The archive contains the solution test_02.slnx for VS2022 with 3 projects targeted to .net481.
    All 3 projects use the PolySharp. The t.test.csproj exposes the problem on build.

    To reproduce the issue:

    1. unpack the solution;
    2. change the PackageReference Include="PolySharp" in the Directory.Build.props to use manually built dev/embedded-types;
    3. build the solution with any predefined configuration. The build fails on the t.test.csproj;

    Regards.

  26. cremor commented on Apr 1, 2026

    @cremor
    Author

    @ns88ns Thanks for your tests, but did you mean to post this in PR #127? At least you should reference your post there.

  27. ns88ns commented on Apr 1, 2026

    @ns88ns

    @cremor - perhaps, you're right, I'm not sure. I searched for issue #127 but found only PR, not the issue.
    The dev/embedded-types was created for this issue... If this report must be posted in the PR #127 - I will wipe it here and move it there.

    Please, let me know.

  28. cremor commented on Apr 1, 2026

    @cremor
    Author

    PR #127 is the PR that wants to merge the branch dev/embedded-types. Since you tested that branch, your comment would best match there.

    But you don't have to delete your comment here. PR #127 would fix this issue here if it was merged, so it's also relevant here.

  29. ns88ns commented on Apr 1, 2026

    @ns88ns

    Re-posted also to the PR #127

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions