Reputation: 51
I am using Visual Studio 2017, with the old style .csproj
file format.
I am trying to build up a set of NuGet packages.
The initial layer (C NuGet package) exposes some piece of core functionality.The middle layer (B NuGet package) pulls in C and provides a set of methods. So, B has a dependency on C. The .nuspec
for B lists C as a dependency.
Finally, I have an application (A Application) that pulls in the B NuGet package. What I am trying to avoid is my application having references to C, but since C is marked as a dependency in B it gets added.
I do not want Visual Studio to add in a reference to C for application A. I just need C artifacts at runtime so that B still works correctly.
A <-- B <-- C
If the C NuGet package has a foo()
method, and I install B NuGet package into application A, application A can use the C.foo()
method. I only want application A to use exposed B methods.
How can I create the B .nuspec
file to add the C NuGet dependency, but limit its usage to only the B NuGet package? Is there some change I need to make to the C .nuspec
file as well?
I have looked into include and exclude flags relating to dependencies, and could not find the combination to achieve what I want.
I tried using the newer .csproj
format to let Visual Studio create the NuGet packages for me, but could not get that to work as I want.
If I remove the unwanted C references from application A, I lose those artifacts at runtime, so that did not work.
I see the DevelopmentDependency
flag which indicates a package should be excluded from the output. I am kind of looking for the notion of a RuntimeDependency
, that is only included in the output.
PrivateAssets
/ SuppressParent
does not sound right, since packages "should be consumed, but not flow to the next project".
Upvotes: 3
Views: 1125
Reputation: 51
I took a much different approach to handle this issue. I am not sure I totally like it, but it serves my needs pretty well.
So, nothing changes with NuGet package C. It gets built and packaged as before.
The goal of NuGet package B was to help facilitate using the logic in C in a service. So, I turned B into a full blown service implementation that still references C. The B NuGet package now consists of one DLL (which contains the service contract interface) that gets pulled into Application A, and uses an Install.ps1 to copy the necessary files into a separate directory. There are no dependencies listed in NuGet B package. So, the only reference in Application A, is that single DLL.
The good is that with everything in separate directories there will be no versioning issues between what B needs and what A needs. Also, A does not get burdened with unnecessary dependencies from B. It isn't the greatest, because some DLLs could be shared between the two.
Upvotes: 2
Reputation: 28116
Finally, I have an application (A Application) that pulls in the B NuGet package. What I am trying to avoid is my application having references to C, but since C is marked as a dependency in B it gets added.
It's expected behavior I think. If we have two nuget packages, A depend B with <dependency id="B" version="xxx" />
in .nuspec
file, the application which consumes Package B
will automatically install and reference Package C
. And this point can be obviously proved when you use packages.config
format to manage nuget packages.
So it's hard to get what you want in this way.
How can I create the B .nuspec file to add the C NuGet dependency, but limit its usage to only the B NuGet package?
When your Package B depend on Package C, if you consume Package B
, it will reference Package C
as well. So there's possibility to do what you want if the Package C is only used to provide C.dll as content during runtime. (It means if we reference Package C directly, it won't reference C.dll directly, only in this way it's possible for what you expected)
But if it's what you want. Why not contain the C.dll
into B.nupkg
. We only need to create B package which contains C.dll(not in lib folder when packing), then when we Consume B package in A, it will only reference B.dll. It works well during build time. And for the runtime, we just need to copy the C.dll
into output folder. Then it works in both build time and runtime.
See Content files element in .nuspec
or including targets in nuget, either of these two ways may help resolve your issuebut since I not familiar with Content files, so I use custom msbuild target to do this, and it works. Feel free to let me know if I misunderstand anything or there's better way :)
Upvotes: 0