1

I am working on a Windows C# .NET 4.5 program that utilizes several NuGet projects to reduce the amount of code I need to write (why reinvent the wheel?). One of these NuGet projects, for whatever reason, has a dependency that overrides one of MSCORLIB's methods used elsewhere in my program.

ReSharper warns me of the ambiguous reference (and I cannot compile obviously), and I cannot for the life of me figure out how to specify the use of MSCORLIB's method over this NuGet project dependency. I spent a couple hours googling and reading different things but cannot find a solution.

The part of my program that has the ambiguous reference error does not rely on the NuGet package's dependency in any way, so if I can just implement MSCORLIB's method in just this spot I will be golden.

Is this even possible? I tried to explicitly add reference to MSCORLIB to the project with ReSharper's "Use this assembly..." but selecting either one did not work, as well as the References tab in Visual Studio.

Anders
  • 12,088
  • 34
  • 98
  • 146
  • Also, if I can find a workaround and it breaks this NuGet package I obviously will have to find an entirely new solution. – Anders Mar 10 '18 at 03:56
  • Have you tried using, at the top of your file: `using NugetRef = NugetPackage.Namespace;` to alias the nuget package reference to disambiguate the call? – Ron Beyer Mar 10 '18 at 04:19
  • Will that work in this case since they reference the same namespace? See this image: https://i.imgur.com/rNHtmOg.png – Anders Mar 10 '18 at 04:22
  • Possibly not in that case... You could load one of them into a new AppDomain dynamically and remove the static reference. – Ron Beyer Mar 10 '18 at 04:25
  • I do not have experience with this (EDIT: the dynamic loading you refer to is what I am referencing). Do you have any material handy I could read up on to see if this is a potential solution? – Anders Mar 10 '18 at 04:27
  • https://learn.microsoft.com/en-us/dotnet/framework/app-domains/how-to-load-assemblies-into-an-application-domain – Ron Beyer Mar 10 '18 at 04:30
  • Thank you much. Would you be able create an answer so if I get a solution from your comments I can credit you for a solution? – Anders Mar 10 '18 at 04:39
  • This is a problem that aliases are used to solve. The standard use case for those is needing to reference two different versions of the same assembly which will have types with exactly the same fully qualified names. See [this question](https://stackoverflow.com/questions/286632/what-use-is-the-aliases-property-of-assembly-references-in-visual-studio-8) for more details. – Mike Zboray Mar 10 '18 at 06:42
  • What *exactly* do you mean by "has a dependency that overrides one of MSCORLIB's methods used elsewhere in my program"? Could you give a concrete example? – Jon Skeet Mar 10 '18 at 10:00

1 Answers1

2

You can resolve this using assembly aliases and extern alias. To resolve this, you will need to edit by hand your projects .csproj file.

If you are using packages.config, look in your .csproj file for the <Reference> element that corresponds to the project bringing in the conflicting type and assign it an alias.

<Reference Include="bouncy_castle_hmac_sha_pcl, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
  <HintPath>..\packages\BouncyCastle-PCL.1.0.0.6\lib\bouncy_castle_hmac_sha_pcl.dll</HintPath>
  <Aliases>bouncy_castle</Aliases>
</Reference>

If you are using PackageReference instead, there won't be a direct <Reference> element, so instead, you need to add a target to assign this value.

<Target Name="AssignAliasesToAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
  <ItemGroup>
    <ReferencePath Condition="'%(FileName)' == 'bouncy_castle_hmac_sha_pcl'">
      <Aliases>bouncy_castle</Aliases>
    </ReferencePath>
  </ItemGroup>
</Target>

Then, you can reload your project. In your C#, add extern alias bouncy_castle; to the top of the file. This will instruct the compiler how to disambiguate between the two types.

extern alias bouncy_castle;
using System.Security.Cryptography;

namespace ClassLibrary2
{
    public class Class1
    {
        public HMACSHA1 Algorithm { get; }
        public bouncy_castle::System.Security.Cryptography.HMACSHA1 TheOtherOne { get; }
    }
}

By the way, see this issue: https://github.com/NuGet/Home/issues/4989

natemcmaster
  • 25,673
  • 6
  • 78
  • 100