8
votes

In our product, we have a few projects. almost each of them is depending on single one, called "core". We are distributing each project as separated nuget package. And for deployment our work for other teams/products nuget works great, it's really big pain during our local job.

Each time when "core" project is changed, we need to rebuild it, build nuget, publish it in some repository, then in other projects make restore. It's take time. And sometimes we need to make changes in core in few iterations. It's fore us to make build-publish nuget-update nuget circle over and over

Best solutions we found so far is to switch nuget references to project references during our local work, and switch it back to nuget when we want to publish it.

But we are not sure if it's the best way.

So, what is the best way to handle nugget references in two local projects without making work harder?

Thanks

4

4 Answers

3
votes

what is the best way to handle nuget references in two local projects without making work harder?

NuGet has many advantages as a package manager for the Microsoft development platform, this does not mean that it is not flawed. Just as you encountered, if the referenced project is modified frequently, we have to rebuild it, build nuget, publish it for each modification. That will bring a lot of boring work. To resolve this disadvantages, the Project-to-project references should be a better way.

The advantage of a project-to-project reference is that it creates a dependency between the projects in the build system. The dependent project will be built if it has changed since the last time the referencing project was built. A file reference does not create a build dependency, so it is possible to build the referencing project without building the dependent project.

So what you have done is the best way. The project-to-project reference should be recommend when the referenced project is modified frequently, the nuget reference is more appropriate when share the reference project to others or publish it.

2
votes

In the Node community, local packages problem is long solved with symbolic links (see this blog post and npm link command).

How it works: the directory of a distributed package is "symlinked" to package source directory. In this way, package consumers are transparently redirected to package source project, and changes in package sources are automatically reflected on the consumer side.

For some reason, NuGet still has no link feature. There is a feature request https://github.com/NuGet/Home/issues/1821, which indicates they have no plans of adding it.

Meanwhile I created a tool, which works similarly to npm link for NuGet packages, you may want to give it a try: https://www.nuget.org/packages/NuLink

1
votes

What I've done in the past was to write a small script that overwrites your Nuget binaries with binaries that you have just compiled.

This way you work around the overhead of packing, distributing and restoring packages every time you change a single character in your Nuget package

...without changing project references in your consuming project

The workflow goes:

  1. Code and build Nuget binaries
  2. Run script overwriting binaries in the /packages folder in the project consuming your Nuget package
  3. Enjoy

I've whipped together a Powershell script that does the job - I use it myself from time to time:

$ErrorActionPreference = 'Stop'

$SourceBasePath     = 'C:\Projects\MyNugetPackage\Main'
$TargetBasePath = 'C:\Projects\MyNugetConsumer\Main'    
$Configuration      = 'bin\debug'

#0 = Source DLL
#1 = Source location in $SourceBasePath
$maps = @(
    ,@('SomeBinary.dll', 'Foo\Bar')
    ,@('AnotherBinary.dll', 'Bar\Baz')
)


foreach($map in $maps) {
    #Find all packages that contains a copy of the source binary
    $targets = Get-ChildItem "$TargetBasePath\$($map[1].Split('\')[0])\packages" -Filter $map[0] -Recurse
    foreach($target in $targets) {

        $sourcePathDll = "$SourceBasePath\$($map[1])\$Configuration\$($map[0])"
        $targetPathDll = Join-Path $target.Directory.FullName $map[0]

        $sourcePathPdb = $sourcePathDll.Replace('.dll', '.pdb')
        $targetPathPdb = $targetPathDll.Replace('.dll', '.pdb')

        Write-Host ''
        Write-Host $sourcePathDll
        Write-Host $targetPathDll
        Write-Host $sourcePathPdb
        Write-Host $targetPathPdb

        if (!(Test-Path $sourcePathDll)) {
            throw "Source not found: ", $sourcePathDll
        }

        if (!(Test-Path $targetPathDll)) {
            throw "Target not found: ", $targetPathDll
        }

        copy $sourcePathDll $targetPathDll
        copy $sourcePathPdb $targetPathPdb
    }
}

You can run into issues with Visual Studio locking the DLL's - there's no such thing as a free lunch I guess :o)

0
votes

Starting with NuGet 3.3 you can just use a local folder and it can host a hierarchical NuGet feed. Make a folder for "local server" and then go there and run "nuget init source dest" where "source" is a folder I have full of *.nupkg" files. Since NuGet Server is pulling from C:\LocalNuGet,you can take a folder filled with NuPkg files (flat) and import them with:

nuget init c:\source c:\localnuget

for detail information please check these

https://github.com/NuGet/NuGetGallery/wiki/Hosting-the-NuGet-Gallery-Locally-in-IIS

http://haacked.com/archive/2010/10/21/hosting-your-own-local-and-remote-nupack-feeds.aspx/