6

I am iteratively developing support libraries in C#, to be put inside a local NuGet repository which resides in my filesystem. I have noticed that whenever I add a NuGet dependency in one of my libraries, and then I reference that library in one of my projects, this automatically gains visibility to all the NuGet dependencies of my library.

This is not always wanted, because the names in my library could collide with the ones in their dependencies. Is there a way to hide dependencies of a referenced library?

Example: I am developing a function named foo() in my library Lib, and this library references a NuGet dependency Dep which also contains a foo() function. Now, if I reference Lib inside a project Proj, what will happen by default is that Proj gains visibility to both Lib and Dep and it could use the foo() from either one of them. The preferred behavior is that Proj only sees Lib.foo()

UPDATE

Maybe this could serve as an example of dependency problem: I have imported both iTextSharp and BouncyCastle in a project, and this lines of code give a compile error:

Org.BouncyCastle.X509.X509CertificateParser cp;
Org.BouncyCastle.X509.X509Certificate[] chain;

It says that both iTextSharp and BouncyCastle contain the fully qualified names of X509CertificateParser and X509Certificate, which means that iTextSharp refers to BouncyCastle and it is visible to anyone who refers iTextSharp in turn, even though it is not listed in the References dropdown in Visual Studio.

Luca L.
  • 75
  • 7
  • 1
    "the names in my library could collide with the ones in their dependencies" - even when fully qualified, i..e by namespace? Can you give a concrete example of what you're trying to avoid? – Jon Skeet Dec 17 '19 at 14:18
  • I edited the question. Is it clearer now? – Luca L. Dec 17 '19 at 14:31
  • 1
    Not really, because it's normally absolutely clear which `foo()` you mean to call because it would be prefixed by an instance or a type name. Can you give a full, concrete example where it's actually confusing? – Jon Skeet Dec 17 '19 at 14:32
  • To be honest the question telling me `Namespaces` never existed. – Eldar Dec 17 '19 at 14:33
  • I think the keyword you are looking for is 'global'. ref: https://stackoverflow.com/a/15022530/3576971. Although I'll suggest to use namespace to distinguish between different classes. – mbshambharkar Dec 17 '19 at 15:49
  • 1
    I'm with Jon here; I don't understand the question. A method call in C# is always qualified either explicitly or implicitly by a *receiver*, which is either an expression that identifies a type, or an expression which evaluates to an instance of that type. How is it possible to have an ambiguous unqualified call? Show us an example please so that we can figure out what you're talking about here. – Eric Lippert Dec 17 '19 at 17:48
  • Maybe you are right: there's always the namespace to disambiguate. However I can't believe that there's no way to hide recursive dependencies in C#... – Luca L. Dec 18 '19 at 09:27
  • https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-namespaces – Hans Passant Dec 19 '19 at 13:48
  • The clarified question is a duplicate of https://stackoverflow.com/questions/286632/what-use-is-the-aliases-property-of-assembly-references-in-visual-studio-8 – Eric Lippert Dec 20 '19 at 19:41

1 Answers1

3

Maybe this could serve as an example of dependency problem: I have imported both iTextSharp and BouncyCastle in a project, and this lines of code give a compile error:

Org.BouncyCastle.X509.X509CertificateParser cp;

It says that both iTextSharp and BouncyCastle contain the fully qualified names of X509CertificateParser and X509Certificate, which means that iTextSharp refers to BouncyCastle and it is visible to anyone who refers iTextSharp in turn, even though it is not listed in the References dropdown in Visual Studio.

Looking at the source code of iTextSharp, it appears at first glance that the authors have simply copy-pasted the BouncyCastle code into their project unchanged, rather than taking a dependency on the assembly. This is a bad practice because it causes exactly the problem you are now experiencing.

If you are in the unfortunate position of being required to use two libraries, one of which has made an exact copy of the other, then as you have discovered, the compiler does not know which one you meant when you give it what looks like a fully-qualified name, and you'll get an ambiguity error.

The best way to solve this problem is do not use libraries that have copy-pasted other libraries into them. But if that is not possible, then there is a way to disambiguate them, and fortunately for you, Jon answered a question on how to do so eleven years ago:

What use is the Aliases property of assembly references in Visual Studio 8

Unfortunately I cannot close this as a duplicate right now, but perhaps someone else can do so.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067