Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referencing multiple package versions within one project with extern aliases #6693

Closed
Athari opened this issue Mar 18, 2018 · 3 comments
Closed
Labels
Resolution:Duplicate This issue appears to be a Duplicate of another issue Type:Feature

Comments

@Athari
Copy link

Athari commented Mar 18, 2018

I need to reference multiple versions of the same package within one project and use extern aliases to use them in code.

Reason: I'm building a package which I want to support multiple versions of a dependency. Having just one package simplifies usage and versioning of the package, but complicates code and uh... project architecture in my solution. More background and reasoning can be found in StackOverflow question Supporting multiple versions of NuGet package in one library / NuGet package.

If I understand correctly, NuGet supports neither referencing multiple versions of a package, nor extern aliases. For extern aliases, there's a workaround, but it doesn't work for me, as my references have the same name. So, I need to find workarounds for both issues.

I kinda got it to work. However, I don't understand many details and receieve tons of warnings. So far, my architecture is:

  • Alba.CsConsoleFormat.Ref.CommandLineParser-1.9.csproj and Alba.CsConsoleFormat.Ref.CommandLineParser-2.2.csproj projects just to reference packages and force NuGet to cache them. Code:

    <ItemGroup>
      <PackageReference Include="CommandLineParser" Version="1.9.71" ReferenceOutputAssembly="false" ExcludeAssets="all" />
    </ItemGroup>
  • Alba.CsConsoleFormat.CommandLineParser.csproj project with the actual code which uses two projects above as dependencies. Code:

    <PropertyGroup>
      <VersionClp19>1.9.71</VersionClp19>
      <VersionClp22>2.2.0</VersionClp22>
      <DefineConstants Condition="'$(TargetFramework)' != 'netstandard1.5'">$(DefineConstants);CLP_19;CLP_22</DefineConstants>
      <DefineConstants Condition="'$(TargetFramework)' == 'netstandard1.5'">$(DefineConstants);CLP_22</DefineConstants>
      <NuGetClp19Dir>$(NuGetPackageRoot)commandlineparser\$(VersionClp19)\lib\</NuGetClp19Dir>
      <NuGetClp22Dir>$(NuGetPackageRoot)commandlineparser\$(VersionClp22)\lib\</NuGetClp22Dir>
    </PropertyGroup>
    
    <ItemGroup>
      <PackageReference Condition="'$(TargetFramework)' != 'netstandard1.5'" Include="CommandLineParser" Version="$(VersionClp19)" ReferenceOutputAssembly="false" ExcludeAssets="compile" />
      <PackageReference Condition="'$(TargetFramework)' == 'netstandard1.5'" Include="CommandLineParser" Version="$(VersionClp22)" ReferenceOutputAssembly="false" ExcludeAssets="compile" />
    </ItemGroup>
    
    <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
      <ProjectReference Include="$(LibraryRefPathPrefix)CommandLineParser-1.9.csproj" ReferenceOutputAssembly="false" ExcludeAssets="all" />
      <ProjectReference Include="$(LibraryRefPathPrefix)CommandLineParser-2.2.csproj" ReferenceOutputAssembly="false" ExcludeAssets="all" />
      <Reference Include="$(NuGetClp19Dir)$(TargetFramework)\CommandLine.dll" Aliases="CommandLineParser_1_9" />
      <Reference Include="$(NuGetClp22Dir)$(TargetFramework)\CommandLine.dll" Aliases="CommandLineParser_2_2" />
    </ItemGroup>
    
    <ItemGroup Condition="'$(TargetFramework)' == 'net40'">
      <Reference Include="$(NuGetClp19Dir)$(TargetFramework)\CommandLine.dll" Aliases="CommandLineParser_1_9" />
      <Reference Include="$(NuGetClp22Dir)$(TargetFramework)\CommandLine.dll" Aliases="CommandLineParser_2_2" />
    </ItemGroup>
    
    <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.5'">
      <Reference Include="$(NuGetClp22Dir)$(TargetFramework)\CommandLine.dll" Aliases="CommandLineParser_2_2" />
      <Compile Remove="Models/OptionInfo19.cs" />
    </ItemGroup>
    
    <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
      <Reference Include="$(NuGetClp19Dir)net45\CommandLine.dll" Aliases="CommandLineParser_1_9" />
      <Reference Include="$(NuGetClp22Dir)netstandard1.5\CommandLine.dll" Aliases="CommandLineParser_2_2" />
    </ItemGroup>

Problems I have:

  1. Projects I use for receiving specific versions of dependency still produce binaries. Ideally, I'd like some sort of project which supports <PackageReference>, but doesn't cause any compilation. Can this be done?

  2. Just ExcludeAssets="all" should probably be enough, but without ReferenceOutputAssembly="false" my build randomly fails (some of devenv build, dotnet build, msbuild, CI AppVeyor build fail, some don't, some always, some only if not incremental, just very inconsistent in general).

  3. I have to include <PackageReference Include="CommandLineParser" /> in the main project, otherwise I can't get NuGet to list the dependencies in .nuspec. If I understand correctly, .nuspec is generated based on project.assets.json, and there's no way to "merge" with manual .nuspec, so there's no other way.

  4. I have to put ExcludeAssets="compile" on <PackageReference>, otherwise I get errors about missing extern aliases. This turns into <dependency exclude="Compile,Build,Analyzers"> in .nuspec, but I don't understand how it actually impacts anything.

  5. The actual range of versions I support is [1.9.71],[2.2.0,), but looks like I can't specify anything like that.

  6. Even if I put ReferenceOutputAssembly="false" ExcludeAssets="all" on <ProjectReference>, it still checks for binary compatibility, so I have to put references into only one framework Condition="'$(TargetFramework)' == 'net45'".

  7. I receive tons of warning about versions:

    • warning NU1701: Package 'CommandLineParser 1.9.71' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETStandard,Version=v2.0'. This package may not be fully compatible with your project.

      I guess <NoWarn>NU1701</NoWarn> would solve that, but I'll leave it for now.

    • C:\Program Files\dotnet\sdk\2.1.4\Microsoft.Common.CurrentVersion.targets(2041,5): warning MSB3243: No way to resolve conflict between "CommandLine, Version=2.2.0.0, Culture=neutral, PublicKeyToken=de6f01bd326f8c32" and "CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32". Choosing "CommandLine, Version=2.2.0.0, Culture=neutral, PublicKeyToken=de6f01bd326f8c32" arbitrarily. [C:\Docs\Projects\CsConsoleFormat\Alba.CsConsoleFormat.CommandLineParser\Alba.CsConsoleFormat.CommandLineParser.csproj]
      Consider app.config remapping of assembly "CommandLine, Culture=neutral, PublicKeyToken=de6f01bd326f8c32" from Version "1.9.71.2" [C:\Users\Athari.nuget\packages\commandlineparser\1.9.71\lib\net40\CommandLine.dll] to Version "2.2.0.0" [C:\Users\Athari.nuget\packages\commandlineparser\2.2.0\lib\net40\CommandLine.dll] to solve conflict and get rid of warning.

      I'm confused on many levels:

      • There's no need to solve any conflicts. The libraries are just references, nothing should be copied. Why do I get this?
      • I can't add "app.config" to a library, can I? Why is it suggested?
      • What does "arbitrarily" mean? It seems to consistently choose the highest version.
    • C:\Program Files\dotnet\sdk\2.1.4\Microsoft.Common.CurrentVersion.targets(2041,5): warning MSB3277: Found conflicts between different versions of "CommandLine" that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. [C:\Docs\Projects\CsConsoleFormat\Alba.CsConsoleFormat.Sample.ProcessManager\Alba.CsConsoleFormat.Sample.ProcessManager.csproj]

      This project references one specific version CommandLine 1.9.17, it references Alba.CsConsoleFormat.CommandLineParser.csproj, which for .NET 4.5 depends on CommandLine >=1.9.17. There's a second-level dependecy on Alba.CsConsoleFormat.Ref.CommandLineParser-2.2.csproj, but shouldn't all these ReferenceOutputAssembly="false" ExcludeAssets="all" make reference irrelevant?

      One time I tried these "verbose" build logs, I got like 100 MB of unreadable logs, so if I don't know what to search for, it won't help me.

Whole CsConsoleFormat project (permalink to current commit).

Any suggestions on how I should approach my requirements? Any hints on how to resolve all issues I mentioned above?

I guess this is the only place where I can get answers.


  • VS: 15.5.6
  • dotnet: 2.1.4
  • OS: Windows 10 64-bit version 1709 build 16299.125
@ancgate
Copy link

ancgate commented Jan 7, 2020

Any updates on this.

@nkolev92
Copy link
Member

nkolev92 commented Apr 6, 2020

Thank you filing this issue.

This issue is a duplicate of #4989.

@nkolev92 nkolev92 closed this as completed Apr 6, 2020
@nkolev92 nkolev92 added Resolution:Duplicate This issue appears to be a Duplicate of another issue Type:Feature labels Apr 6, 2020
@fowl2
Copy link

fowl2 commented Jul 25, 2023

Turns out the #4989 doesn't actually solve the problem for multiple versions, so we can continue holding out hope in #12400.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution:Duplicate This issue appears to be a Duplicate of another issue Type:Feature
Projects
None yet
Development

No branches or pull requests

4 participants