1

We have a solution with many projects using the DevExpress XAF framework. Many of these projects use packages from DevExpress. A lot of times something goes wrong and references are broken. Is there a way to force all projects to use remote online sources? I'm aiming for a composer / npm / .. like experience.

Also can we force to use a non-nuget.org repo for this as devexpress has it's own repo? It's currently listed in the nuget.config in the root of the solution. For me microsoft documentation does not provide an answer.

It's not entirely clear to me when a package appears in the packages folder. When to declaration appears in the .csproj or when it appears in the packages.config. A more uniform and central place to keep track of the packages would be great.

Can somebody please explain how they do it in their projects and why?

edit: We use git, not TFS. Also I'd prefer not to store binaries (the dll's) in version control. I added this as multiple people suggested this as an option.

online Thomas
  • 8,864
  • 6
  • 44
  • 85
  • We use [NuGet Package Restore](https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#:~:text=Restore%20using%20MSBuild%201%20Open%20a%20Developer%20command,the%20following%20command%20to%20rebuild%20the%20project.%20) for this. (Actually, we use the command-line to do it using `msbuild -t:restore` but the link I posted covers several ways of doing a package restore.) – Matthew Watson Oct 12 '21 at 09:00
  • @MatthewWatson Thank you for your response, however this is known to me. But local resources will still come from local paths. I would like to have an easy way to force them to be downloaded. This question is more about how to cleanly manage the dependencies, rather than how to restore itself. – online Thomas Oct 12 '21 at 09:03
  • When you said "A lot of times something goes wrong", did you mean that when you push and read from the tfs? or can you please be more specific? nuget problems are very common, does it says that it can't find the package even though it's there? or it does find it, but a different version? ...etc. – Warios Oct 21 '21 at 08:22
  • 1
    @Warios References get broken and can only be fixed by re-installing. I will add a screenshot when it happens again. Although probably now it won't happen anymore in the near future :) – online Thomas Oct 21 '21 at 08:32
  • It seems like the tfs is not restoring the packages correctly, see this: https://stackoverflow.com/questions/67104998/nuget-package-is-not-being-installed-when-reading-from-tfs – Warios Oct 21 '21 at 09:25
  • @Warios We use git – online Thomas Oct 21 '21 at 10:01

2 Answers2

1

Developer's Local Environment

When managing large solutions with several dependencies, including nuget, 3rd party dll's (DevExpress), etc... it is key to ensure whatever solution is used is not dependent upon a developer's local directory structure.

For example, if the solution is always looking to restore / find / copy some dependencies from:

D:\org-name\dependencies\third-party-1\

Then you will run into issues when the developer does not have a "D" drive, in this case. This may not be the convention for you, but the point is to not lock down dependency resolution to a hard-coded directory.

3rd Party Dependencies

I understand the desire to not want the dll's stored in your git repo. However, when it comes to 3rd party assemblies, relying on their company nuget feed1 or some other external URL will eventually come to bite you in the a** when their server goes offline, or your internet has gone offline. Or worse yet, their service goes out of business.

1 This is a 3rd party nuget feed. Not the official nuget/ms feeds.

The most reliable method of ensuring a project's 3rd party assemblies can be restored is to include them in your repo.

The strategy we used was to include a folder in the root of the solution which contained the current version of the assemblies from the 3rd party. And then reference those assemblies in the project; not from their company's nuget feed (or similar).

Example

\Solution Root
  \Binaries (or name it whatever you want)
    \DevExpress
      - DevExpress.Utils.v16.1.dll
      - DevExpress.Utils.v16.1.xml
      - etc..
    \Another-Third-Party
      - foo.dll
      - foo.xml
      - etc...
  \ProjectA
    - ProjectA.csproj
  \ ProjectB
    - {you get the idea...}
  - .gitignore
  - your-solution.sln

The great thing about this strategy is that you will always have the exact version of the dll's referenced in your solution for the current release. There will never be a need to fetch them from an external server.

A word of caution: this strategy can back-fire if one of your dev's adds another DevExpress assembly through their installer or the DevExpress nuget feed. So your team has to understand that all DevExpress assemblies are always referenced from your \Solution Root\Binaries\DevExpress directory. You will know there is an incorrect reference when your build server blows up (never install DevExpress crap on your build server!)

Nuget Dependencies

Nuget assemblies do not need to be stored in your repo as they are guaranteed to always be available for the version you reference.

However, I would recommend you always add the nuget dependencies being referenced into your repo for every release. This will ensure you will always have them available no matter what may happen.

As far as packages.config vs project.csproj nuget package references, you'll need to work through those on a case-by-case basis, re: the very old nuget convention was to have a packages.config. The current convetion is to reference nuget packages in your .csproj file. What I'd recommend is extracting the references out of packages.config and pulling them into your .csproj files. This may be a bit time-consuming, but you'll end up with a common convention across all projects in the solution.

NPM

NPM is package manager. Nuget is a package manager. Neither will package up commercially purchased packages; they are almost always added through a manual process or the company's nuget feed which requires authorization.

In other words, as you're dealing with commercially purchased dependencies from DevExpress, you're going to have to either use their private nuget feed, or use a strategy similar to what I've outlined above.

Summary

Although not mentioned, you could provision your own private nuget server which maintains all your 3rd party dependencies. However, it is a PITA to keep it up to date. The strategy I outlined above worked really well and was incredibly easy to maintain.

Hopefully, this gets you going in a good direction.

Metro Smurf
  • 37,266
  • 20
  • 108
  • 140
0

I've personally found it best to have a single main directory to contain all of my NuGet packages at, and have all my solutions and projects refer to that directory.

You can do this by manually setting the default location for NuGet to install its packages to by modifying your %AppData%\Roaming\NuGet.config XML file to include the following element:

<config>
  <add key="repositoryPath" value="C:\NuGetPackages" />
</config>

Replacing my value with whatever value you choose. Now, this won't change the location of the NuGet package locations for existing projects, so unfortunately you'll have to go through the pain of removing those references, and then re-adding them one by one through the NuGet interface again using the new default download/install location. But, once you've done all of that, it really simplifies the process and maintenance of NuGet packages. It also prevents you from having five versions of the same NuGet package in five different solution subdirectories.

And, if you want to ensure that you can restore any version of them, you can always add them into Team Foundation Server (if you use TFS, that is).

Westley Bennett
  • 554
  • 4
  • 19