Nuget package release branches

Topics: General
Jan 6, 2013 at 6:50 PM

Hi, I will demonstrate my problem through a concrete example.

I have been developing an Entity Framework based tool that currently supports every .net40<= release. Now, If I wanted to add .net45 specific features, I could just create a .net45 platform directory in the NuGet package and place a separate assemby in it. In the past, Entity Framework releases were tied to the release of .NET framework releases. This is about to change, EF is going to be released separately.

The platform directory solution will not work anymore since my library has to be recompiled against EF6 separately too, and this follows that EF6 will become a NuGet package dependency. I do not want to enforce the users to have the latest release of EF and I want to support legacy EF versions as much a possible.

So I would publish 4 different releases for my library:

  1. depends on .net 4.0
  2. depends on .net 4.5
  3. depends on .net 4.0 and ef 6
  4. depends on .net 4.5 and ef 6

How should I organize my Nuget package? Currently my best shot is to have a separate package id for 3 and 4, but I want to avoid this. Also, what should be the proper versioning schema for this?

Remember, my key requirement is to not enforce updating EF, so if someone executed a package update (e.g. update-package cmdlet) the process should not update the EF package, just download and reference the most appropriate release of my library. I could not find out how to achieve this in Nuget.

This feature would be good for other framework too. Let's assume a company uses "Foo" as an essential component. A 3rd party developer is developing a "Foo.Ex" component that extends the functionality of "Foo". The company wants to use the latest version of "Foo.Ex", but does not want to use the latest version of "Foo", because it contains some breaking changes (that might be completely unrelated to Foo.Ex).

Jan 8, 2013 at 8:59 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jan 8, 2013 at 9:05 PM

Hello tamasflamich,

I've created a bug to track this issue; I'm inclined to agree that this is a scenario we don't have good support for right now.

In the meantime, you should be able to support scenarios like this by finding the specific version of one of the EF assemblies in your package's install script (see http://stackoverflow.com/questions/3267009/get-file-version-and-assembly-version-of-dlls-in-current-directory-and-all-sub for an example of how to do this in code), and branching your install logic accordingly.  Let me know if that doesn't work.

HTH,
Clay

Jan 11, 2013 at 9:33 AM

Hello,

Thank you for you suggestion. So if I understood correctly, these things should be done:

  • I should not add EF as a dependency package.
  • I should move the assemblies of my library from the lib folder to something else (e.g. assemblies, or is there a good convention?) and build a custom folder structure for the different variations of my library (e.g.  assemblies/net40/pre-ef6, assemblies/net45/pre-ef6, assemblies/net40/ef6 ... etc).
  • I should create tools/install.ps1 and tools/uninstall.ps1 scripts that reference and dereference the appropriate variant of the library, respectively.
  • The install script should search for an EntityFramework.dll reference in the project that the package being installed in. However, I think it should search in a recursive way (check assembly references of other referenced projects too), am I right?
Jan 15, 2013 at 9:37 PM

I believe you can accomplish what you need today.

1. Foo

- Contains the core assemblies for the Foo package

- Can have a versioning scheme however it wants

2. Foo.EntityFramework Version 5.0.0

- Has a dependency on Foo

- Has a dependency on EntityFramework, with the version range as [5.0.0,6.0.0)

3. Foo.EntityFramework Version 6.0.0

- Has a dependency on Foo

- Has a dependency on EntityFramework with the version range as [6.0.0,7.0.0)

 

Then, if the user has EntityFramework 5.0.0 installed, they could get Foo.EntityFramework 5.0.0.  With EF 6.0.0, they'd get Foo.EntityFramework 6.0.0.  And without EntityFramework, they could just get Foo.

Does this seem reasonable?  The logic for the lib folder addition could get really nasty and goes against the principles of NuGet's simplicity for resolving references.

Jan 19, 2013 at 3:39 PM

Thank you for your suggestion.

I also thought about something similar. However, I have several problem with this approach:

  • The user has to specify the package version explicitly. If he/she simply calls Install-Package Foo.Entityframework, then NuGet will pull the latest version of supported EF too.
  • Multiple packages could bring confusion to the users.
  • The differences between preEF6 and EF6 that matter do not make necessary to decouple my assembly.

Probably I will use the install script based approach and forget about using the lib folder. My situation is really not typical, so it might not worth to implement a generic solution for my problem.