1

Update for clarification:

I have a project which is exposed as Nuget package. I need it to be public to my solution assemblies but private to who ever will consume my package. Is there a way to accomplish that?

Original question:

A project I'm working on is currently using 2 entities projects and it's written over .Net Standard 2.0 framework:

Contract.csproj
Contract.Internal.csproj

The first is configured to be exposed for consumers using a private Nuget server, while the second is for internal use of my solution projects.
The thing is that both has pretty much the same classes except few that are for my solution internal use only.

Is there a way to merge them to a single project and configure some classes to be exposed in the NuGet package while others are not?

I read on the ExcludeAssets/IncludeAssets tags that can be added to the csproj PackageReference, but the docs and all the examples I saw are referring dependencies and their versions and not the project classes.

Also, if you have other solution, you work with your projects some other way on this one (Or even think that I find myself with that scenario is wrong) I'll be more than happy if you share you thoughts on this.

YanivHer
  • 123
  • 14
  • Why not *only* have the classes for internal use in Contract.Internal and let your internal tools reference both assemblies? – Klaus Gütter Sep 25 '21 at 09:15

3 Answers3

1

If you want to expose certain classes from your project while keeping other classes internal, you can use C# access modifiers.

For example, a class prefixed with internal will be only visible inside your project:

internal class Foo { }

A class prefixed with public will be accessible for others:

public class Bar { }
Wouter de Kort
  • 39,090
  • 12
  • 84
  • 103
  • marking it as as internal won't solve my problem since it will be hidden from my other solution assemblies. As I stated in my question, I need them to be public to my assemblies but private to who ever will consume my package. – YanivHer Sep 27 '21 at 05:47
  • Which you can do; https://stackoverflow.com/questions/920844/how-can-i-access-an-internal-class-from-an-external-assembly – Jeremy Lakeman Sep 27 '21 at 06:18
0

I think Wouter's answer should help resolve your problem. But I want to highlight another approach to a similar problem that may help you or other folks in the future.

Since there is an interface/functionality in Contract.Internal.csproj that is internal but needed in Contract.csproj, as a possible solution, instead of making its interface public, you can restrict it with internal modifier. And in order to access that internal interface in Contract.csproj, you can use this answer.

What you'll have to do, is to grant access of the internals visibility to Contract.csproj by modifying the AssemblyInfo.cs file of the Contract.Internal.csproj the following way:

[assembly: InternalsVisibleTo("Contract.Internal")]
David Oganov
  • 976
  • 1
  • 11
  • 23
0

A single package is the wrong approach here because it violates the principle of separation of concerns. Instead, you should have MyPackage that has all the public code and is intended to be consumed by anyone, then for your own internal use have MyPackage.Private that references MyPackage. Your users reference MyPackage, you reference MyPackage.Private, and everything is simple.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138