NuGet packages that create a large number of non-required project references - nuget

I am reviewing our TFS access code after we upgraded to VS 2017 and VSTS Online.
I found out from another question on this site that the recommended way to access the TFS libraries is via a NuGetPackage.
Great, that's surely better than referencing from the Team Explorer installation folder.
However, the NuGet package in question added over 45 references to my project.
I believe I am only using 4-6 of them.
I found this question which discussed the fact that the package files do not have to go into source control.
That's good to know.
However, the references have been added as "Copy Local" and so they are all currently being copied to my output directory. This has caused my application to more than treble in size. It just doesn't seem like good practice.
Do people usually just ignore this and trade off against the fact they are getting great dependency management?
Or manually remove the non-required references...? Do future updates put the references back?
Or have I incorrectly consumed the package in some way...?
There are a lot of NuGet questions on this site. I did search but please accept my apologies if this is a duplicate.

Do people usually just ignore this and trade off against the fact they are getting great dependency management?
Add all dependencies to the project is the default behavior of NuGet. At this moment, there is not such option so that we could choose some of those dependencies.
Although all dependencies are added to the project as "Copy Local", when we publish our application, we could exclude those unneeded dependencies by changing the Publish Status from Include (Auto) to Exclude:
In this case, those non-required references are not included into the application.
Or manually remove the non-required references...? Do future updates
put the references back?
Yes, you can manually remove those non-required references, but when you update the package next time, those removed references would be re-add again.
Besides, as you said, you are only using 4-6 of them. You can try to custom a nuget package only including those 4-6 references.
Create nuget package from dlls
Hope this helps.

Related

Creating and installing a nuget package with referenced project

I want to publish a dotnetcore2.1 nuget package using dotnet pack and dotnet nuget push.
The package is a project in a solution that has a reference to another project in that solution.
I can't install the package because it can't resolve the referenced project.
I tried doing this, and it includes the referenced package .dll to the .nupkg file, but it's still not possible to install it.
I can't really figure out what is the 'expected' way to do this. I definitely don't intend to publish the referenced project to the nuget feed.
Is this a massive oversight by microsoft or am I not getting something?
You have a project A that you want to pack and this project references another project B that is not usable or not intended for use on its own, but from a design perspective it is reasonable to keep it separate for purposes like reuse. In the end the package for project A should also contain project B.
Indeed this is an issue tracked in the NuGet repository, issue 3891. In both this and your link to the corresponding .NET project issue there are some workaround involving MS Build, but there is no official support, yet.
As stated in the above issue, even Microsoft seems to be aware of this issue and simply creates packages for the referenced projects that are marked with
Please do not reference directly
I think that until project references are supported, the safest way is to do same, although it is not convenient. Workarounds may become obsolete or cause strange behavior. However, since your referenced project is only intended to be used in your main library, you could include it like this
<PackageReference Include="LLL.Client" Version="1.0.0" PrivateAssets="all"/>
This way, the package contents from your referenced project will only be included in your project and consumers of your main package will not be able to see them.

How to prevent NuGet version drift in a big monolithic (sigh :-() application (multiple solutions, many projects in each)?

We are building all the solutions to a shared bin directory. Having different projects reference different versions of the same dependency is not healthy for our build.
So, we consolidated the dependencies - great. But now the versions start to drift again. We do not want to consolidate them manually every now and then - we want to prevent the drift completely.
Why we do not want to use Paket? The main reason is that it seems we would lose the ability to migrate the NuGet package dependencies to the new PackageReference items in the projects. So, currently we have package.config files, but we plan to replace them with the respective PackageReferences. That means we will use internal NuGet support by msbuild, which seems to leave no place for Paket.
Now, I assume we are not unique in this world and others have the same problem as we are. How do you solve it?
EDIT 1
We have our internal NuGet repo, but we use it for dependencies which do not have organic representation in Nuget.org and for sharing our own internal packages.
One approach is to consume only from the internal NuGet repository. This has challenges, like:
Who uploads the dependencies there? Developers? But then how to make sure they do not upload different versions of the same dependency? Dedicated people? Then they become a bottleneck.
Small thing, but we need to block commits to the central NuGet.config
Uploading a dependency to the internal NuGet repo is not immediate. You cannot just download it from NuGet.org and upload to the internal one, because that would miss any transitive dependencies. So, a process should be built around it.
It is all possible, but I am reluctant to go down that route ... Must be a better way.
EDIT 2
While we do plan to migrate to PackageReference, it will take time. And unfortunately as long as we have Silverlight (another year, at least) a whole bunch of projects in the dedicated Silverlight solution (80+) will not be migrated to PackageReference, because by doing so it becomes impossible to debug the code with VS 2015.
Next, suppose we do migrate ALL the projects and then externalize all the PackageReference items to a single targets file imported by all the projects. This is feasible when using a shared bin directory as we plan to do. But when inspected in VS 2017 this setup communicates a wrongful picture that every single project depends on the entire set of NuGet dependencies.
I would rather avoid this.
Once you move to PackageReference, you can take advantage of MSBuild. For example, you can have a MSBuild file that contains all your dependency versions. It could be a file that you need to <Import ... /> in all your csproj files, or you could use Directory.Build.props. Finally, in each of your projects, change the version number in any <PackageReference to a MSBuild variable that uses the property you previously defined. Most of Microsoft's open source repositories use this technique, with minor variations about file names and whether it's imported automatically with Directory.Build.props, or an explicit <Import ... />.
While you can still use the Package Manager UI in Visual Studio to check for updates, you won't be able to update the package versions with it (at least, it won't preserve how and where the versions are defined). However, just make sure your MSBuild file that defines the versions is in your solution, so you can trivially open the file in Solution Explorer and then type the new version number in. Adding new package references is slightly more effort, but it's generally not done often, and it's still very easy with SDK-style projects, since Visual Studio lets you edit the csproj while the project is still loaded.
Since you didn't accept the other solution, maybe you could take a look at paket
It's a package manager for dotnet than (among other feature) holds solution wide dependency lock file. It is very customizable, and while it solves LOTS of problems, as any tool, creates some new ones. In my experience, the new ones are far less infuriating :)

Working with Multiple Nuget Projects in one Solution

I have 2 projects: A & B that I want to publish as NuGet Packages but I don't know how to develop efficiently in Visual Studio.
Solution 1
Project A
Project B - references Project A as NuGet reference
When I make a change to Project A that is needed in Project B do I have to publish Project A? Is there a way to get the project reference functionality during development? Maybe Project B shouldn't reference Project A via NuGet?
There must be a good way to handle this situation, no? I've reviewed the NuGet docs but I couldn't find anything. There must be docs/blogs/SO posts to read more about this... I'm struggling to come up w/ the right keywords.
You might want to look at this extension: NuGet Reference Switcher for Visual Studio 2017
This allows you to switch between NuGet packages and project references during development.
Check out this blog post: https://markheath.net/post/multiple-nuget-single-repo
Basically, dotnet pack handles this for you automatically. You use regular project references when developing.
There must be a good way to handle this situation, no?
The best solutions is that 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. Just like NuGet Reference Switcher doing.
For some more detailed info, you can check following thread:
nuget packages in local work
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.
You could add following Post-build event command to pack your project after building.
"the nuget.exe path\nuget.exe" pack "project path\NuGetPackageLibrary.csproj" -OutputDirectory "Your target path"
When your build successful, the package in target path will be replaced by the latest version.

How to maintain the "content" source-code of a Nuget package?

I am in process of setting up a whole series of NuGet packages for our framework. Beside the simple binary-packages (.dll's for modules of the framework) there are also packages that deliver source-code into the projects that are using them done with the \content directory in the NuGet package.
To develop this source-code I have a test-/sandbox project. I develop/debug/fix the code in this peoject and if its final for the next release, I copy it over to the package's content-folder where I replace things like $rootnamespace$ etc. This needs to be done for each and every version of the package.
Another way is to keep only the final source with the $rootnamespace$ tags in it and maintain that directly. But then testing/debugging would be done by re-adding the package to a test-project and debug it there, go pack to the package content, modify it, re-build and re-add and test it again.
So I see two ways to maintain the content-sourccode (none of them is really good):
Keep source-code in \content as small as possible and deploy as much as possible as binaries.
Generate the \content using some transformation engine (eg. T4) from the sandbox/dev-project. What engine would be best to use for this?
In short: I didn't find a good workflow yet to maintain the "content" source-code of NuGet packages. How are you guys doing this? Any ideas for that workflow?
Check the http://github.com/maartenba/MvcSiteMapProvider build. It is customized quite a bit but basically does a find/replace on several namespaces and replaces them with replacement tokens right before packaging.

Adding supporting libraries to NuGet package without adding as references

I have a group of DLLs: some are meant to be directly referenced by the project and others are just supporting those DLLs and aren't meant for direct interaction. I know how to add files to be project references for NuGet: put them in the lib folder. But how do I get DLLs to be around to get picked up during builds but not be project references?
pranavkm on the NuGet CodePlex discussions pointed me here:
http://docs.nuget.org/docs/reference/nuspec-reference#Specifying_Explicit_Assembly_References