Process for Creating and Consuming Nuget Packages - c#

I am currently in a situation where our team is creating a nuget package DLL A and consuming that package in an application Application B. A and B are maintained as separate Git repositories.
Right now my process is:
Make changes to A
Commit and push to prerelease branch(CI is run which generates pre-release package on our Artifactory instance)
Nuget update B
Consume Changes in B
While nothing in this process takes terribly long, it does add up over time. Previously A was part of the solution of B and we could just use project references to quickly iterate.
My question is, is there a better way to approach this process for creating and consuming Nuget packages? I would like this to work for multiple team members who each have their development folder structure setup the way they like it. We have considered using local nuget packages, but I am unsure how to set that up so it works for everyone on the team consistently (and that still requires manually updating B's nuget packages).
I am using Visual Studio 2015 Update 3 with projects that all target .net 4.6.1. Mainly I am working with Class Libraries and WPF Applications that use nuget package.config to manage nuget references.

Related

Optimal configuration for both development and distribution stages of the nuget package

I want to produce a set of NuGet packages written in C#.
These packages are class libraries, referencing each other in the way like:
MyGreatPackage.Core - no references
MyGreatPackage.Feature1 - references the core
MyGreatPackage.Feature2 - also references the core
MyGreatPackage.Feature2.SubFeature1 - references the Feature2 package and, respectively, the core
During the development stage, there is often a lack of real-world use-cases, so I decided to develop those packages as a part of a real project.
To implement it, I extract those packages as a git submodule(s) and connect them to the repository of the main application.
As a result, there is a .net solution like that:
MyApp.sln
MyApp.Host.csproj
MyApp.ClassLibrary1.csproj - references MyGreatPackage.Core.csproj
MyGreatPackage.Core.csproj - in the submodule
MyGreatPackage.Feature1.csproj - in the submodule, references MyGreatPackage.Core.csproj
MyGreatPackage.Feature2.csproj (references the core csproj)
MyGreatPackage.Feature1.SubFeature1.csproj (references the feature1 csproj)
Everything goes smoothly here, as I can develop both the app and the packages.
But, when it comes to the distribution stage, this configuration doesn't seem to work, as I can't simply push the submodule contents to the NuGet and replace the submodule references with the NuGet references.
The problem is that the Feature1 package when prepared for pushing to the NuGet, should have a reference to the MyGreatPackage.Core package and not a reference to the csproj. Also, the Feature2 package and subfeature1 package.
So how should I prepare this setup for both the development and the distribution stage?
I don't know a trivial answer to your question. But here are some possibilities:
Use some kind of tool that easily allows you to switch between project references (for working locally, being able to easily debug code, etc.) and NuGet references (for publishing your applications). RicoSuter/DNT has a switch-to-projects command that does exactly this.
Always use NuGet package references, and publish new versions whenever you need it: either to a local or to a private NuGet feed. You can debug NuGet packages with the use of tools like SourceLink, or punctually include projects. Depending how tightly coupled your projects are and the stage of development you're at, this option can be more or less viable.
The poor's man alternative to the first one when using the second approach: having a git stash that includes those projects in the solution and replaces the NuGet references with the project ones. If you work on your own, this can be an option to sporadically change to project references and debug something. If used often, this can be a pain due to those change being accidentally commited, etc.

Is it possible to automatically update Nuget packages after a WinForms installation?

Let's say I have a windows forms application with a few Nuget packages that are important and need to be kept up-to date.
Is it somehow possible to update Nuget packages programatically from a non-development environment? With a non-development environment I mean a random user that is running the WinForms application (having it installed on their pc).
I've read some things about using nuget.exe, but updating the nuget packages should result in .dll files to be placed in the installation folder.
You can do that, but you should not do it. NuGet packages are development dependecies and not meant to be updated arbitrarily in an already compiled application or at the customer site, because
You cannot be sure that your application will work with the updated assemblies, since they may introduce changes that will lead to crashes or unexpected behavior at runtime.
NuGet packages not only include assemblies, but also build scripts and resources that may depend on MS Build or other tools that run in your development environment to be deployed or even included in your own assembly, like embedded resources.
Packages have dependecies to assemblies and other packages. You will need to update the dependencies, too, and there is a lot of potential to break anything with it.
You would need to include the NuGet CLI executable when shipping your application and your customer would need to a allow for pulling and installing packages.
Installing packages without testing them first may harm the quality of your application and could also introduce security issues. Remember that you may be dealing with executables from a potentially public package source.
That being said, do not do it. Instead, follow a responsible software develpment cycle, where you update packages and test your application throughly before delivery and provide frequent updates of you whole application to your customers.
Nevertheless, for educational purposes, you can install packages locally with Nuget CLI tools, in this example nuget.exe. You need to specify the package identifier, the output directory and the framework, like net472 for .NET Franmework 4.7.2. This will extract the contents, as well as the package itself to the output folder in the package folder structure that will not match your target directory structure. From there, you would need to copy the assets that you need into your install directory e.g. with a copy script. Apart from not being the right thing to do, this is very cumbersome and most likely deemed to fail.
nuget install <PackageId> -OutputDirectory <OutputDirectory> -Framework <Framework>
If it is auto-update, just think about if some method is supported in old version of dll, and in the new version it has been removed. 
Though you can update the package suring build time.
Enable automatic package restore by choosing Tools > Options > NuGet Package Manager, and then selecting Automatically check for missing packages during build in Visual Studio under Package Restore.
Reference: https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#restore-packages-automatically-using-visual-studio

Is it possible to develop using local projects instead of having to publish every change to nuget?

I'm coding on a project that has several Azure-based applications, as well as several Windows services, etc. Needless to say, it's just a bunch of individual applications that are deployed out to Azure, or elsewhere, and expected are all expected to work together.
We use Nuget for our underlying library project versioning. Every feature or change results in a bump to the Nuget version, a package published to our private Nuget server, and a subsequent update to every other application that needs the update. This is currently a tedious manual task, but is not even my most immediate source of frustration.
The thing that I struggle with the most, currently, is while doing development on a feature that requires changes across the entire set of applications, from bottom to top, and having to constantly push out Nuget packages and update Nuget packages just to even develop and debug.
Prior to using Nuget, we may have just added all of these projects as direct dependencies on disk, which removes versioning but instantly lets me develop against my local changes.
Now with Nuget, I can't develop against local changes without pushing out a new package.
Is there a workflow that I'm missing that would allow me to still use Nuget but also be able to make changes and work locally without having to push and pull Nuget packages all the time?
Can I somehow develop against local projects, but also somehow have the project dependencies know to use the Nuget packages?
I ran into this issue when setting up a shared NuGet repo for my company. You can set up local a NuGet feed and 'publish' just by dropping files to a folder. This is extremely useful for local testing before you're ready to publish to the shared repo.
Also, NuGet uses semantic versioning. I find it useful to have pre-release versions by using a tag like MyLibrary.1.0.0-prerelease-12345 so you can still have incremental builds, but most other apps will not be notified of the changes until you create a major release such as MyLibrary.1.0.1. This could require you to make some changes to your DevOps process, but it allows multiple developers to test your package before 'officially' releasing it.
If your issue is that you want to be able to easily update multiple applications locally and test those changes. I have occasionally found it useful to create a single solution file encompassing all my projects so I can quickly open, update, and build everything in one Visual Studio instance. However, this solution is not particularly scalable, so you might be better off writing PowerShell scripts for automation.
Update Another solution that you might find useful is NuLink. I have never tried it so I can't actually endorse it, but it purports to provide similar functionality to npm link (and actually uses symlinks just like npm does).
Given the projects are all in the same repo, just use project references instead of package references.
When you pack a project, NuGet will convert project references into NuGet dependencies, and the dependency version will be the same as what the other project is if/when it is packed.
Check this answer, where you could:
build the dependency's code locally to produce DLLs.
replace the DLLs in your machine's nuget cache folder corresponding your dependency with the local DLLs produced in the previous step
That's a quick way to see changes locally without publish-consume cycles

NuGet cross-project dependencies in shared library

The setup: I've created a library targeting .Net Standard 2.0 in VS 2017 and this library uses NuGet to reference a 3rd party driver and manage its dependencies. So far, so good.
The next step is to create an application that uses the (shared) library, in this case a console app targeting .Net Core. I can, of course, add a reference to the DLL(s) that form the shared library. That compiles but doesn't run because the 3rd party stuff is missing. I could of course just copy all required DLLs to the application but for obvious reasons I'd rather use NuGet.
I'm not very experienced with NuGet, never used it in this constellation and having read articles like NuGet cross-project dependency I'm getting the impression I need to fiddle with the application's project file in order to get the library in a complete form but surely that can't be the way forward.
So my question is - is the problem on the side of the library, i.e. do I need to build or export in a particular way, or on the side of the application which, IMHO, shouldn't need to know that level of detail about some library it consumes.
Any help much appreciated!
I'm sharing a large, complicated library this way with several other solutions.
First, set up your library. Right click on the library's project name and choose Properties. About halfway down you'll see a tab labeled Packages. You can use that to auto-generate the NuGet package every time you rebuild the project. Just increment the version number. I use four position version numbering -- the first three are semver-style (major release, minor release, patch release), and the fourth one I increment manually for each new build.
I recommend creating a folder on your drive or network specifically for your local NuGet packages. You can create folders under that for each project. Then you point your debug and release build output to that project folder, and the NuGet package will be generated there, too.
Finally, back in Visual Studio, go to Tools -> Options -> NuGet Package Manager -> Package Sources and add that top-level folder as a package source.
From there it's simple -- open your NuGet dependencies in your consuming app. There's a drop-down at the top right where you can choose the package source. It will automatically search all the child folders and find whatever packages you've created. Now when you tweak your library, it's just a single click to update the client apps.

Best way to implement Nuget packages

I'm making a complex application and I would create more little packages to include. I have installed a nuget package "CreateNugetPackageFromProjectAfterEachBuild" that create or update automatically a package of my application. In this moment I create two types of package Debug and Release but from VS15 I see only one package to install. Why? Is the correct way to work?
Thank you!
It's not clear from your question, what exactly you want to create NuGet packages for.
In any case, it makes no sense to have separate Release and Debug versions of packages. You could separate them by version, though:
have stable releases built as Release
have prereleases built as Debug
Make sure that each NuGet package you build has a different version, otherwise you'll cause yourself a lot of grief. NuGet has no way to differentiate between different packages with the same version. You can only update a package to a different version and individual versions are cached. It's best you create and publish new package versions from a build server, not directly from a development environment to avoid confusion.
Also, keep in mind that you should really only be using NuGet packages for libraries which have an independent lifecycle and are used in multiple projects. You will want stabilize a library before creating a new version of the package and then stick with this version in your application until you have a new stable version of the library ready.
If your libraries are more tightly coupled to the application - they don't have a separate lifecycle and you tend to modify them together with the application, then referencing them in the application as a NuGet package is not that good of an idea. You're better off just having both the libraries and the application as part of the same solution.

Categories

Resources