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

How to reference different version dependencies for different frameworks #3377

Closed
Bikeman868 opened this issue Oct 1, 2018 · 15 comments
Closed

Comments

@Bikeman868
Copy link
Contributor

I am using the Microsoft.Owin NuGet package in my solution.

My solution needs to be compiled for .Net 4.0 and .Net 4.5. I am doing this by having two .csproj files in the same folder. Both of the .csproj files reference all of the same source files but target different .Net framework versions and specify different output folders.

This works great with NuGet, but I can not see how to make this work with Paket because projects compiled for .Net 4.0 must reference Microsoft.Owin version 2.1.0 and projects compiled for .Net 4.5 must reference Microsoft.Owin version 3.0.1 and I can only have one paket.references file in my project folder.

You can see my source code here

Is this possible with Paket?

@BlythMeister
Copy link
Contributor

You will need to use paket groups to do this.

@Bikeman868
Copy link
Contributor Author

Bikeman868 commented Oct 1, 2018 via email

@BlythMeister
Copy link
Contributor

Why not have 2 paket reference files...

@baronfel
Copy link
Contributor

baronfel commented Oct 1, 2018

Yes, split out your framework-dependent deps into two groups in your paket.dependencies file. Each group should have the appropriate framework constraint in it.

source ...

nuget ...
nuget ...

group Net40Deps
  source normal_nuget
  framework: net40
  
  nuget Microsoft.Owin 2.1.0

group Net45Deps
  source normal_nuget
  framework: net45

  nuget Microsoft.Owin 3.0.1

We do this exact practice in several places and it works well. Nuget packaging and everything works as expected, with conditional group references.

Then, in the single, unified paket.references, you can conditionally include some deps or the other based on framework like so:

# deps from main group
Blah
Foo
Bar

#deps for net40
group Net40Deps
  Microsoft.Owin framework: net40

# deps for net45
group Net45Deps
  Microsoft.Owin framework: net45

@Bikeman868
Copy link
Contributor Author

Bikeman868 commented Oct 2, 2018 via email

@Bikeman868
Copy link
Contributor Author

Bikeman868 commented Oct 2, 2018 via email

@Bikeman868
Copy link
Contributor Author

I can not find any documentation on conditional groups, but some of the error messages referred to them, so they are supported in some way.

I tried making files exactly as you suggested, and many other variations of placement for the various parts of the syntax, but I could not find any combination that worked.

With this paket.dependencies file

framework: net40, net45
storage: packages

source https://nuget.org/api/v2

// These dependencies are fixed to a specific version because
// they are passed on in Nuspec files

nuget Ioc.Modules = 1.3.2
nuget Newtonsoft.Json = 7.0.1
nuget Svg = 2.3.0
nuget Urchin.Client = 1.2.1
nuget Moq = 4.2.1507.0118
nuget Moq.Modules = 1.0.2

nuget Owin = 1.0
nuget Owin.Framework = 2.6.8
nuget Owin.Framework.Mocks = 2.6.8

// These dependencies are not passed on in Nuspec files

nuget NUnit ~> 3.5

// These dependencies are only for the sample apps

nuget Ioc.Modules.Ninject ~> 1.3
nuget Microsoft.Owin.Host.SystemWeb = 2.1.0
nuget Microsoft.Web.Infrastructure = 1.0.0.0
nuget Owin.Framework.DefaultDocument ~> 2.6
nuget Owin.Framework.Documenter ~> 2.6
nuget Owin.Framework.ExceptionReporter ~> 2.6
nuget Owin.Framework.NotFound ~> 2.6
nuget Owin.Framework.Urchin ~> 2.6
nuget Ninject = 3.2.2.0

// These Microsoft packages need specific versions for specific .Net frameworks

group net40 
  source https://nuget.org/api/v2
  framework: net40
  nuget Microsoft.Owin = 2.1.0
  
group net45 
  source https://nuget.org/api/v2
  framework: net45
  nuget Microsoft.Owin = 3.0.1

and this paket.references file

Ioc.Modules
Newtonsoft.Json
Owin.Framework

group net40
  Microsoft.Owin framework: net40

group net45
  Microsoft.Owin framework: net45

The output from paket install is

Paket failed with -> Installation Errors : Package Microsoft.Owin is referenced in different versions in {path}.csproj (4.0 vs 2.1), (inspect the lockfile for details) to resolve this either add all dependencies to a single group (to get a unified resolution) or use a condition on both groups and control compilation yourself.

@Bikeman868
Copy link
Contributor Author

For the sake of completeness the paket.lock file contains:

STORAGE: PACKAGES
RESTRICTION: || (== net40) (== net45)
NUGET
  remote: https://www.nuget.org/api/v2
    Ioc.Modules (1.3.2)
    Ioc.Modules.Ninject (1.3.1)
      Ioc.Modules (>= 1.3.1)
      Ninject (>= 3.2.2)
    Microsoft.Owin (4.0)
      Owin (>= 1.0)
    Microsoft.Owin.Host.SystemWeb (2.1)
      Microsoft.Owin (>= 2.1)
      Microsoft.Web.Infrastructure (>= 1.0) - restriction: == net40
      Owin (>= 1.0)
    Microsoft.Web.Infrastructure (1.0)
    Moq (4.2.1507.118)
    Moq.Modules (1.0.2)
      Moq (>= 4.2.1507.118)
    Newtonsoft.Json (7.0.1)
    Ninject (3.2.2)
    NUnit (3.10.1)
    Owin (1.0)
    Owin.Framework (2.6.8)
      Ioc.Modules (>= 1.3.2)
      Microsoft.Owin (>= 2.1)
      Owin (>= 1.0)
    Owin.Framework.DefaultDocument (2.6.3)
      Ioc.Modules (>= 1.3.2)
      Newtonsoft.Json (>= 7.0.1)
      Owin.Framework (>= 2.6.8)
    Owin.Framework.Documenter (2.6.5)
      Ioc.Modules (>= 1.3.1)
      Newtonsoft.Json (>= 7.0.1)
      Owin.Framework (>= 2.6.7)
    Owin.Framework.ExceptionReporter (2.6.2)
      Ioc.Modules (>= 1.3.1)
      Newtonsoft.Json (>= 7.0.1)
      Owin.Framework (>= 2.6.7)
    Owin.Framework.Mocks (2.6.8)
      Moq.Modules (>= 1.0.2)
      NUnit (>= 3.5)
      Owin.Framework (>= 2.6.8)
    Owin.Framework.NotFound (2.6.2)
      Ioc.Modules (>= 1.3.1)
      Owin.Framework (>= 2.6.7)
    Owin.Framework.Urchin (2.6.8)
      Ioc.Modules (>= 1.3.2)
      Newtonsoft.Json (>= 7.0.1)
      Owin.Framework (>= 2.6.8)
      Urchin.Client (>= 1.2.1)
    Svg (2.3)
    Urchin.Client (1.2.1)
      Ioc.Modules (>= 1.2.1)
      Newtonsoft.Json (>= 7.0.1)

GROUP net40
RESTRICTION: == net40
NUGET
  remote: https://www.nuget.org/api/v2
    Microsoft.Owin (2.1)
      Owin (>= 1.0)
    Owin (1.0)

GROUP net45
RESTRICTION: == net45
NUGET
  remote: https://www.nuget.org/api/v2
    Microsoft.Owin (3.0.1)
      Owin (>= 1.0)
    Owin (1.0)

@Bikeman868
Copy link
Contributor Author

Well... an hour later and I did get it working. The framework: net40 qualifiers are not necessary in the paket.references file. The difficult and fragile part is that you need to get the whole dependency tree into the same group, but some of the modules I am referencing are not version specific and Paket complains if I put these into groups so I can't just duplicate everything in both groups. This means that there are definitely dependency graphs that are impossible to configure in Paket.

@JimHume
Copy link

JimHume commented Aug 10, 2019

My team and I hit this issue while trying to share common libraries across projects within the solution who may target framework, netstandard, or netcore.

Paket will not properly restore packages, yielding a significant amount of MSB3245, MSB warnings (> 300) when building, meaning it flat-out couldn't find the package and won't do anything about it.

To compound the issue, Paket seemingly doesn't respect when a framework was upgraded when in this confused state. Despite performing an 'add' on every single dependency in every single project effectively re-installing every possible dependency, paket leaves the package hint paths pointing to an older framework version than what the projects were updated to.

@Bikeman868 : did you have much success getting around this or did you abandon it / stick with an alternate pattern?

This is also similar to what we were experiencing: dotnet/standard#481
I have not tried the forceful binding redirect option yet however--I'm hesitant to do that when there is still an underlying issue with the graph that might not be solvable. I should point out that the issue mentioned above in dotnet/standard ultimately resulted in this announcement: dotnet/announcements#31

@forki
Copy link
Member

forki commented Aug 11, 2019

What do you mean it does not restore packages properly?

@JimHume
Copy link

JimHume commented Aug 11, 2019

@forki Transitives, in particular, will not be copied to the output directory. They may “restore” in the sense that they make it to the package cache, but they will not be copied to the output folder which causes runtime errors.

Some of these transitives, when converted/specified as a direct dependency in the paket.references file, will still not be copied to the output directory. That one in particular is especially frustrating.

I am using the latest non-preview Visual Studio 2019 at the time of writing, but I’m trying to get a CI build working. I’m therefore using MSBuild from the command line for the majority of builds. There are also dotnet build commands included, but those all work without issue—its only the .NET framework projects that are encountering this issue.

@forki
Copy link
Member

forki commented Aug 12, 2019

do you have a small repro?

@JimHume
Copy link

JimHume commented Aug 12, 2019

@forki This repository is somewhat large and is the result of attempting to merge together a few different repositories into a single solution.
I may be able to come up with a small repro, but it may be difficult to do so. I'm mostly looking for information about workarounds and whatnot, as this may be the result of any number of issues that were encountered while attempting to merge said repositories.

I'm not logging a bug against paket, I'm mostly looking to see if the issue was worked around in the past or if there is perhaps some way to accomplish what the original author was trying to do. I don't want to place the burden on anyone other than myself at this point basically.

@Bikeman868
Copy link
Contributor Author

Bikeman868 commented Aug 14, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants