Skip to content

Cannot use attribute due to internal access modifier #15

Closed

Description

@jfevia

Description
Cannot use attributes in project that references another project containing the NuGet package.

To Reproduce

  1. Create two projects.
  2. Project 1 has a reference to the NuGet package.
  3. Project 2 has a reference to Project 1

Version Info

  • PropertyChanged.SourceGenerator version: 1.0.3

Additional Info
I would expect to be able to use the attributes in Project 2. However, the attributes have the internal access modifier, thus I have to reference the NuGet package in each project where I am planning on using the attributes.

Can the attributes have the public access modifier instead?

Activity

  1. canton7 commented on Apr 19, 2022

    @canton7
    Owner

    I would expect to be able to use the attributes in Project 2

    Maybe a silly question, but why?

    The attribute is there so that the source generator knows to process those fields. That only happens if the source generator is actually referenced by the project which is using the attribute. If you were able to reference the attribute from another project, the source generator wouldn't notice, because it wouldn't be processing that other project.

  2. jfevia commented on Apr 19, 2022

    @jfevia
    Author

    Makes sense, this sounds to me more like a limitation of source generators in general and not specifically for this source generator.

  3. canton7 commented on Apr 19, 2022

    @canton7
    Owner

    On the other hand, source generators are a build-time dependency: they're there to aid the compilation process. If a project references a source generator package, the compiled assembly won't reference anything, and it won't add any dlls to your bin folder.

    Just because one project happens to use a source generator to help it build, doesn't necessarily mean that any projects which reference it want to use that same source generator: indeed, forcing that source generator on them might break something! For instance, there are quite a few INPC source generators, and it would be annoying if you were forced to use a particular one just because one of your dependencies decided to use it internally.

    I'd call this a good design decision, rather than a limitation of SGs. If your Project 2 wants to use a particular SG, it just has to reference it.

  4. jfevia commented on Apr 22, 2022

    @jfevia
    Author

    The CommunityToolkit provides this feature (i.e: I can reference Project 2 in Project 1 and have the attributes generate the code).

    Personally, I find this useful for maintenance. Otherwise I have to go to every project and reference the NuGet package, which becomes an issue for large solutions.

    I'm reopening this issue since shouldn't have rushed to close it.

  5. reopened this on Apr 22, 2022
  6. canton7 commented on Apr 22, 2022

    @canton7
    Owner

    This is because Microsoft.Toolkit.Mvvm is a nuget package which contains both DLLs and source generators. As such, it doesn't get a <PrivateAssets>all</PrivateAssets> property in the csproj, which means that its source generators are exported to any projects which reference it.

    You can see the source generators in the referencing project under Dependencies -> Analyzers in the Solution Explorer. The SG is installed into your referencing project: it's just that it was inherited from a referenced project, rather than explicitly installed.

    You can remove the <PrivateAssets>all</PrivateAssets> from the PackageReference property for PropertyChanged.SourceGenerator in your csproj if you want, and then it will get exported to any projects which depend on that project.

    But, the attributes still need to stay internal in this case. Otherwise you'll have one version of the attributes emitted into the dependency, and a second version with the same name and namespace emitted into the project which depends on it, and any attempt to reference that attribute will raise a warning because it's ambiguous.

    Note that in the community toolkit, the attributes are put into a separate assembly, and aren't emitted into the project directly. This means that all of your projects reference the same dll and have access to the same version of the attributes. So you don't have the problems which come from each project having its own definition of the attributes.

    I specifically don't want PropertyChanged.SourceGenerator to add any runtime dependencies. The attributes are only needed during compilation: they're just useless baggage after that, and forcing the user to reference a dll just to be able to see these attributes which have no use at runtime is a waste.

    It sounds like removing <PrivateAssets>all</PrivateAssets> will just do what you want. This has the same effect as adding a reference to the source generator to the including project.

    Making the attributes public while keeping <PrivateAssets>all</PrivateAssets> will not work for the reasons I explained in my previous post. Unless the SG is running on the referencing project, the attributes themselves do nothing.

  7. canton7 commented on Apr 22, 2022

    @canton7
    Owner

    Also, if all of your projects have the same set of dependencies, you can define them in a Directory.Build.props file which is automatically included into all projects. Alternatively, you can avoid the magic inclusion and instead use an explicit <Import Project="Path/To/File.props"/>.

    You can either put the PackageReference elements into that .props file, or you can define a property e.g. <PropertyChangedVersion>1.0.0</PropertyChangedVersion>, then do e.g. <ProjectReference Include="PropertyChanged.SourceGenerator" Version="$(PropertyChangedVersion)"/>.

  8. canton7 commented on Apr 23, 2022

    @canton7
    Owner

    Moving this to a discussion, as there's no way this change can be made, and this issue has turned into user support.

  9. Repository owner locked and limited conversation to collaborators on Apr 23, 2022
  10. converted this issue into a discussion #16 on Apr 23, 2022
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