How to reference NuGet packages? - c#

I'm a newcomer to .NET world, and at this point I'm super confused about the packages, references and how to reference them in my c# project.
I have 3 project in my solution:
DataAccess - which contains the logic for accessing data, the mapping between DTOs and entities, etc.,
DataAccessTest - contains unit tests for DataAccess project,
Service - wraps the DataAccess project into a Windows service.
Now, DataAccess project references AutoMapper (among others) to help with data transformation. It's included in <PackageReference /> element in the csproj file. It seems to be working fine when I'm doing dotnet restore, however dotnet build fails when trying to resolve the namespaces! The same goes for JetBrains Rider - it doesn't find the namespaces until I explicitly reference them in <Reference>!
Not sure if related, but the same goes for the dependent projects. For example, DataAccessTest references the DataAccess project - so that the test will run. However, it still requires adding the transitive dependencies (for example AutoMapper), on top of the project reference.
Is this the intended behavior? Do you need to keep both <PackageReference> and <Reference> for project to compile correctly?

In C# you Have to take care about referencing to other projects. if one project has been referenced to other project, the other project couldn't use or reference to first project. if you did, it will gives you compilation Error.

You need to install Nuget packages for each project that references methods in that package. So, if only your DataAccess project requires AutoMapper, it should be sufficient to add the Nuget package to that project. The solution is not much more than a wrapper around a bunch of projects. You should be able to publish a project separately. The project will take care of its own dependencies. It is hard to find out what goes wqrong. It may be helpful if you create a small testproject, e.g. create an empty console project and a DataAccess Library. Then you add a Nuget package to your DataAccess library and copile all stuff. In this way you can try to find out what is goning wrong. Make sure to install the Nuget Packages for the correct project (I got this wrong several times before I discovered how it really worked).

Related

Use local source code of NuGet package to debug and edit code

I have a solution with an application project (ASP.NET Core) and multiple library projects. I want to separate some of the library projects into a separate solution and turn them into NuGet packages.
With the libraries in the same solution I could of course simply edit something in a library, run the application and see how it works (and debug, if necessary).
However, when I turn the libraries into a NuGet package, the application references the packages from our private NuGet feed instead of the project file.
My question is: is it possible to locally "override" the package reference and use the local source code instead? That way I could still edit the libraries and see the effects in the application. This is a lot easier than having to publish a new package for every small change (especially when trying to fix an issue or implementing a new feature).
DNT (Dot Net Tools) does this. You can specify which packages to switch and where they are.
See the 'switch-to-packages' and 'switch-to-projects' command line switches.
Its a bit fiddley as (when I last tried) you had to create a config file that holds the mapping, and it seems to be easy to break the switching. But its something.
https://github.com/RicoSuter/DNT
I've not tried it, but maybe you can use it to switch to packages on a commit for the build server to work correctly? (Or to ensure the references are correct in source control?)
If you want to use nuget in your project and debug, even modify the source files of the nuget packages, this is not a good choice because you should build the nuget project(generate the new changed dll) and repack it as a nuget package, then reinstall, to enable the changes. It is too complex.
Once you install the nuget, no matter how many changes you make, it’s useless. The nuget installed at this time is the version you made before any changes. No matter how you change it, it is the previous version. The version stays at that timestamp, unless you repackage the project. Generate nupkg and update the nuget version.
So nuget is not a good choice for your situation, you should use ProjectReference.
Directly use the ProjectReference to reference two source projects, build at the same time, and get the changed parts at the same time.
ProjectReference could cross two different solutions.
Add this on the main project:
<ItemGroup>
<!--add any nuget project'csproj file like this to debug its source code-->
<ProjectReference Include="..\xxx\xxx.csproj">
</ProjectReference>
</ItemGroup>
If the proejct is out of the solution, you could directly use the full path of the nuget project's csproj to connect it.
I'm not sure what you mean by "override" but you can always add the library project to your ASP.NET Core solution and reference it like normal project references. A project referenced within a solution doesn't have to be physically placed in the same folder as the solution itself.
This, however, does require that any developer on the project has both GIT repositories cloned locally (given your two solutions are located in separate GIT repos) in order to be able to build the ASP.NET Core solution. But I don't really see that as a downside.

How to exclude a dependency from nuget package in Visual studio

I have a solution that consume a nuget that have all DTO classes(DataObjects).
When developing I want to create new DTO's. To avoid to have to add the DTO to the external project DataObjects and recompile and republish the nuget just to have access to the new DTO in my project, I have created a project(DevObjects) that have the same namespace.
I just pop a new DTO class into DevObjects and continue developing.
When I'm done with that particular job I move the DTO to the DataObjects recompile and publish the nuget.
This works fine except that when I publish the the library that I was working on as a nuget, it list DevObjects as a dependency even thou it is not referenced in code.
How can I exclude DevObjects from the library nuget?
The only workaround I can think of is to publish a dummy nuget of DevObjects just to make nuget happy, but it does not feel like a palatable solution.
When I'm done with that particular job I move the DTO to the
DataObjects recompile and publish the nuget.
I think you have added project reference like DevObjects which contains the file DTO into DataObjects project Also, l think the projects are based on Net Standard. When you package DataObjects, it will generate the dependency to DevObjects. This is the normal behavior.
In a way, when you package the project as nuget, the generation of dependencies really means adding project references.
How can I exclude DevObjects from the library nuget?
You can just remove DevObjects by some changes into DataObjects.csproj
> change the include into remove
<ProjectReference Remove="..\xxxx\DevObjects.csproj" />
Besides, you can exclude the reference project by UI Control.(Right-click on DataObjects-->Dependencies-->Add Reference-->Projects-->uncheck DevObjects)
Conclusion
When you package a project, the Project Reference adds a dependency to your nuget package. So if you do not want to have this dependency, you can just add the DTO class as an Existing Item into DataObjects project. Hope it could help you.

Developing and debugging projects in mutli-repository in Visual Studio

This is the basics of the problem I am having (of course it is oversimplified for the sake of the question):
I have 2 projects in a solution stored in mono-repository:
Project1 - outputs a library
Project2 - outputs an executable
When Project2 references Project1.
I would like to move to multi-repository where Project1 will be stored in different Repository from Project2.
Project1 will output a nuget package and Project2 will reference it instead the project itself.
The issue I am facing: in current situation (mono-repository) when during development I introduce a feature in
Project2 that also requires a change in Project1 it is not a problem. If there are problems I can discover it
during development time.
In a new way (multi-repository) I first need to make a change to Project1, create nuget and push it to nuget
store, then update reference in Project2. If I would have problems in Project1, I must go back to Project1,
fix the issue and push it again, update reference in Project2 and so on. Also, losing the benefit of debugging
both projects.
Is there a solution to this approach? To focus my question: if I have source codes of both projects on my dev machine,
is it possible somehow to instruct Visual Studio to use source code instead of referenced Nuget for debugging?
Hope I explained it right and clear as possible...
If you have two different projects and both of them are in different repositories, you could add the library as a submodule of the first project. I'm assuming you're using git. You could do this simply by:
git submodule add <link for the other repo>
In visual studio you just add the project to the same solution and then reference library from the executable. I'm not sure if that would do the trick for you, but I hope that works.
We have the exact same problem in our company.
This is 2 part problem.
First part is to have both repositories near each other... There are more options, we were deciding between these 2:
git submodule
meta repository (it is a compromise between mono-repository and multi-repository) you have 2 repositories you want to connect, so you create 3rd repository as a meta-repository via https://github.com/mateodelnorte/meta
Second part is how to connect those 2 repositories so that they are debuggable, but still apart each other... We though of these 3 ways:
new .sln in meta repository that will reference both projects (this didn't cut it, because we already been in a position when we had multiple .sln files and maintaining them is not that easy, because when you add some project into one, you have to add it to the other solutions and this goes sideways really quick)
using Reference and PackageReference with Condition - locally for debugging when .dll is build in ProjA then the ProjB would use "Reference", if not the ProjB would use PackageReference => this was our main solution to our problem until we did it like that... (Because we have more than 2 projects ProjA -> ProjB -> ProjC.. The problem here was when it was built locally, referenced via Reference DLL, then ProjA was not visible from ProjC, but when built via CI and referenced via PackageReference, then ProjA was visible from ProjC)
using only Nugets - Every build of ProjA it will create nuget locally (pre-release) and in ProjB, we would reference that via wild-cards. This works, until you make a second change into ProjA, because ProjB will cache that nuget in C:/Users//.nuget/packages :( so when building ProjA and packing the nuget we clear the newly built nuget from this packages folder. You have to restore ProjB every time you make change into ProjA, but this is where we landed as a final solution for now.
So the final solution for us is:
meta-repository for like 5 other repositories
for debugging we use locally built nugets with constant version of "major.minor.patch.65534-local"
for CI we use the same nuget packaging but we override the local version with
feature branches "major.minor.patch.build_number-branch_name" (having -something after the version makes that nuget pre-release)
master/main branch "major.minor.path.build_number"

Sharing assemblies between projects in a solution

I have a solution that has a project that has a class that I'd like to share with another project in the same solution.
This class depends on a library that was pulled in from nuget.
Because the second project hasn't pulled this same library from nuget, the class execution fails (despite the second project depending on the first).
Up to this point, I've just been going and adding the same nuget packages to multiple projects.
This seems terribly unwieldy as when I need to update one project, I have to remember to update them all, or depend on tests, which seems like a great opportunity for bugs to slip through the cracks.
How can I go about sharing these dependencies between multiple projects in the same solution?
I create a sample solution based on your description, I found the dependencies nuget library could be found automatically in other projects that reference Class1 project. But if I set the Copy to Local property as false for the nuget library in Class1 project references, I will get an error message about could not find the dependencies when running other projects.
So please check the Copy to Local property for the nuget library in your Class1 project to confirm it is set as True.

How does 'DNU RESTORE' determine if a dependency is a project reference rather than a package reference?

I'm getting my knickers in a twist with 'project' versus 'package' (ie Nuget package) references in asp.net 5.0. I'd really like for someone to explain a bit more fully the way references are pulled in in asp.net 5.0. How does a 'dnu restore' determine if something is a project reference rather than a package reference?
I had thought that a reference would be pulled in as a project if the projects were in the same directory, but this is clearly not the whole story. It does appear that you can have a deeper directory nesting and still pick up the project reference.
Here is an outline of my common project structure:
I've got a set of projects, some of which reference one another. There are libraries called TextHelpers and MathHelpers and a project called MainProject. The libraries live in a folder called Libraries, and the MainProject lives in a folder called Tools. This separation is necessary as Libraries and Tools belong to different Git repos:
Root/Libraries/TextHelpers.Project1 - version 1.0.0-*
Root/Libraries/TextHelpers.Project2 - version 1.0.0-*
Root/Libraries/MathHelpers.Project1 - version 1.0.0-*
Root/Libraries/MathHelpers.Project2 - version 1.0.0-*
Root/Tools/MainProject - version 1.0.0-*
Usually MainProject references the libraries as Nuget packages from a private Nuget repository (just a folder on the file system) which serves the libraries.
While I'm building MainProject, however, sometimes I need to make a change to one of the library projects, or sometimes I'd like to step into the files without using a Nuget symbol server. For this reason, I'd like to switch to referencing the (live) projects rather than from the (static) Nuget packages. How would I do this?
I've discovered this much so far: if I have a global.json file, a 'dnu restore' creates a project.lock.json with 'project' rather than 'package' references. Is this the whole story?
dnu and dnx look in the following folders:
The folder where the current project is (that means the parent folder of the folder containing the project.json of the current project). E.g. if you have repo/src/project1/project.json it will look in repo/src
Any other folder included in global.json
Then the algorithm is really naive: if it finds a folder with the name matching the package in any the folders mentioned above it will assume those are the sources for that package.
For example, if you have
src/P1/project.json
src/System.Collections/project.json
and in src/P1/project.json you have a reference to System.Collections, it will use src/System.Collection instead of the NuGet package System.Collections. Projects take precedence over packages.
Caveats:
Since the algoritm looks in the current folder and everything in global.json you might be able to reference some projects from one folder but not another. If in my previous example you'd add a test/T1/project.json project but src is not in global.json then the projects in src will reference System.Collections the project while T1 will reference the package (installed in the global packages folder).
There's no verification to see if the project reference is actually that package. If the name matches, it's a match. So an empty project could replace any package.
If you have multiple project with the same name you can get in trouble.
Hope this helps and answers your question.
Side note: with dotnet (the tool replacing dnx) you can specify for every reference if you want the project or the package to have higher priority.

Categories