1

Simple setup here:

  • Project A - .NET 4.7.2 framework library project
    • PackageReference to SeriLog 2.9.0
      • ExcludeAssets="runtime",
      • PrivateAssets="none", this is optional because by default it should copy DLLs (setting = "runtime")
  • TestProject B - .NET 4.7.2 framework unit test project
    • Project A is added as ProjectReference
    • SeriLog DLL and all dependencies should be copied here

Output: The SeriLog DLL is not copied to the output folder of ProjectA but also not to TestProject B. TestProjectB should contain from my perspective the SeriLog.dll. Am I missing something? Or any other options to achieve that?

Remarks: As far as I understood from the PackageReference format specification, I'm using the attributes correctly.

The ExcludeAssets attribute controls the assets for the project where it has been defined. PrivateAssets controls the flow to projects which are using the Project A.

fl0tschi
  • 101
  • 1
  • 6
  • Are you actually using symbols from the referenced assemblies? If Project A doesn't call anything in the Serilog assembly it probably isn't going to get copy-localed – rbennett485 Feb 10 '20 at 22:12
  • Does your test project use the PackageReference nuget type? (either SDK-based project, a `` item in the csproj file or `PackageReference` property in the csproj) – Martin Ullrich Feb 11 '20 at 12:03
  • @MartinUllrich yes, I'm using PackageReference – fl0tschi Feb 12 '20 at 10:45
  • @rbennett485 I just use code from SeriLog because I had the same feeling this could make the difference, but it didnt. – fl0tschi Feb 12 '20 at 10:46

1 Answers1

5

From the docs you linked:

ExcludeAssets:

These assets will not be consumed

runtime:

Contents of the lib and runtimes folder and controls whether these assemblies will be copied out to the build output directory

so, ExcludeAssets="runtime" explcitly means "don't copy dlls". I'd suggest removing any usage of ExcludeAssets and PrivateAssets and let NuGet use its defaults. If you don't want NuGet's default behaviour, then start using these keywords.

However, there's another thing going on as well. You said your test project is a non-SDK style project. It's possible to target the .NET Framework from an SDK style project, but unfortunatly Visual Studio's templates call them ".NET Core" or '.NET Standard", so people incorrectly assume they can't target .NET Framework. Anyway, while packages are transitive for projects using PackageReference, SDK style projects are always PackageReference, even when there are no packages referenced. However, non-SDK style projects are not. You either need to have one PackageReference in the project or excplicitly set the MSBuild property RestoreProjectStyle to PackageReference. Otherwise NuGet will look for a packages.config file and if that's not found, NuGet considers the project to not use NuGet at all.

Although, it occurs to me now that your test project almost certainly contains references to packages, at least the test framework itself. If those references are via packages.config, this is a known incompatibility. packages.config projects that have project references to PackageReference projects do not completely work properly. There's better compatibility the other way around, or alternatively migrate the test project to PackageReference as well. Honestly I'd strongly suggest migrating all projects that you can to SDK style, even if you keep targeting the .NET Framework. It's the future of .NET and the tools work better. Fewer of these little gotchas.

If the test project is using PackageReference already, then the problem is just that the ExcludeAssets="runtime" is being applied transitively, and by removing it from your referenced project, it will automatically flow to the test project.

zivkan
  • 12,793
  • 2
  • 34
  • 51
  • Yeah thanks, this has been mentioned by a guy above, but I'm using RestoreProjectStyle. And more important: I don't want to have NuGet default behavior. I don't need all DLLs needed for the ProjectA in the output folder. Thats what I want to achieve. – fl0tschi Feb 12 '20 at 10:48
  • When you are saying ExcludeAssets is working like you said, what is the purpose of PrivateAssets then. What I understood was that exclude assets controls the asset for the ProjectA and private assets controls it for the the consumer projects. – fl0tschi Feb 12 '20 at 12:43
  • The migration to SDK style project format would be an option, if this would work. I set the same there it is also not working. Looks like I'm just misunderstanding how **ExcludeAssets** and **PrivateAssets** are working. – fl0tschi Feb 12 '20 at 16:31
  • 1
    ExcludeAssets means don't use the asset type at all. Pretend the package doesn't contain it at all. PrivateAssets means use the assets in this project only, don't flow it transitively to other projects. Considering you're referencing ProjectA from another project, that suggests it's a class library. What's the harm in letting Serilog's dlls being copied to ProjectA's bin directory? Why don't you want it to be copied? – zivkan Feb 13 '20 at 13:52
  • This is just an example, we have a lot of more projects where we don't need to have the packagereferences copied to the class library output folder. So there is no way of controlling the flow of packagereferences to the consumer projects and disabling it for class libraries? I don't want to reference all necessary assemblies to the consumer projects which are needed by every class library – fl0tschi Feb 14 '20 at 09:04
  • Actually I would like to have a behavior of Private="true" on the packagereference, but only true for the defining class library :-) the consumer project should still get this reference correctly. Maybe do-able via a MSBuild target? – fl0tschi Feb 14 '20 at 11:12