When I try to add a package reference to the .csproj file I am having the problem that the actual DLL is not referenced in the project. My example is:
<ItemGroup>
<PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version>
</PackageReference>
</ItemGroup>
The package appears in the Nuget package manager but not in the project's "References" list and the assembly cannot be accessed from the project.
I am using Visual Studio 15.7.4
Thanks
Related
I am trying to create a NuGet package that deploys some T4 .ttinclude files which in turn rely on a number of referenced assemblies. But I'm having issues in consuming projects when I try to enable
The .ttinclude files have been designed to reference required assemblies using the following syntax:
<## assembly name="$(TargetDir)WidgetDatabase.dll" #>
In my NuGet package's target file, I configure T4ParameterValues so that the $(TargetDir) is passed to the T4 text transformer:
<ItemGroup>
<T4ParameterValues Include="TargetDir">
<Value>$(TargetDir)</Value>
<Visible>false</Visible>
</T4ParameterValues>
</ItemGroup>
In the target .csproj, I have the following:
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="WidgetDatabase">
<Version>0.8.1-alpha</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\TextTemplating\Microsoft.TextTemplating.targets" />
The problem is that the T4 Text Transform occurs before the build, but this means that none of the referenced assemblies are copied into $(TargetDir). How can I force the dependencies to be copied into the $(TargetDir) prior to the text transform target running?
This question is related, but doesn't satisfactorily resolve this issue.
I was facing the same problem and I managed to solve this by referencing the assembly from the NuGet package folder instead of trying to copy it to $(TargetDir).
NuGet 5.0 provides a GeneratePathProperty property that you can add to the PackageReference. This will create a MSBuild property that points to the location from which the package will be consumed:
<ItemGroup>
<PackageReference Include="WidgetDatabase" GeneratePathProperty="true">
<Version>0.8.1-alpha</Version>
</PackageReference>
</ItemGroup>
This property can then be added to T4ParameterValues so it can be consumed from your T4 template:
<ItemGroup>
<T4ParameterValues Include="PkgWidgetDatabase">
<Value>$(PkgWidgetDatabase)</Value>
<Visible>false</Visible>
</T4ParameterValues>
</ItemGroup>
<## assembly name="$(PkgWidgetDatabase)\lib\netstandard2.0\WidgetDatabase.dll" #>
The nice thing about this approach is that it works in MSBuild and in Visual Studio design-time.
I am trying to learn and understand nuget and msbuild in .NET Core by examining and manually editing project files (.csproj in .NET Core 2.2).
So when I create WebApi project, the .csproj file looks like this:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
</Project>
Notice that there is no Version attribute specified for the first PackageReference.
Now if I specify it to be the latest stable version 2.2.3 like this:
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.3" />
I get build warning NETSDK1071 which says:
A PackageReference to 'Microsoft.AspNetCore.App' specified a Version
of 2.2.3. Specifying the version of this package is not recommended.
For more information, see https://aka.ms/sdkimplicitrefs
This warning is not shown when Version attribute is omitted so I was wondering how is nuget package Version resolved when not set explicitly?
Also, how does dotnet build knows which version of a nuget package is recommended with the current project settings?
From the link in the warning, you can learn that it is not a regular package, but Meta-package.
It's mean that this package depends on your TargetFramework, and this is mean that when you target to a specific framework that installed in your machine (as SDK), the package will be taken from the specific SDK.
I have a test project which reference NUnit3TestAdapter. I do not this reference to be copied over to the projects that depend on this one.
I thought setting PrivateAssets = All would do it, but apparently I misunderstand how it works, because it does not have the desired effect.
Here is the code:
Rollup\Rollup.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\UITests\UITests.csproj"/>
</ItemGroup>
</Project>
UITests\UITests.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
Directory.Build.rsp
.\Rollup.sln /restore /v:m
After I run msbuild all is built, but I can see NUnit3TestAdapter is in the bin folder for Rollup.
What am I missing?
(https://github.com/Microsoft/msbuild/issues/3996)
PrivateAssets works as expected but the NUnit test adapter NuGet package adds an MSBuild target to the build that adds a few dll files as content items to the project, which then flow transitively through the build - this has the same effect as if you added a text file and set its "Copy to Output Directory" property.
The NUnit3TestAdapter.props contains definitions like:
<Content Include="$(MSBuildThisFileDirectory)NUnit3.TestAdapter.dll">
<Link>NUnit3.TestAdapter.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
You should see these files if you click the "Show All Files" in the Visual Studio solution explorer.
Note that test projects aren't really supposed to be packaged or referenced. They should be leaf projects. The test project templates even contain an <IsPackable>false</…> definition and XUnit's core package also adds it as an imported MSBuild file. The test frameworks expect you to use their abstraction libraries and not runtime assemblies / test adapter packages for projects that share tests or test logic.
I am writing custom MSBuild Target, that replaces some of <PackageReference> for <ProjectReference>, under specific conditions.
I have following msbuild target:
<Target Name="ApplyProjectRedirects"
BeforeTargets="_GenerateDotnetCliToolReferenceSpecs;_GenerateProjectRestoreGraphPerFramework;_GenerateRestoreGraphWalkPerFramework;CollectPackageReferences;BeforeResolveReferences;ResolveAssemblyReferences"
AfterTargets="PaketRestore">
<ItemGroup>
<!-- remove packages we are redirecting to projects, and include the projects -->
<PackageReference Remove="#(ExcludePackageReferences)" />
<ProjectReference Include="#(IncludeProjectPaths)" />
</ItemGroup>
<ItemGroup>
<!-- include the packages in visual studio 'nuget' display, so we know what we redirected -->
<PackageReference Include="#(ExcludePackageReferences)">
<ExcludeAssets>all</ExcludeAssets>
</PackageReference>
</ItemGroup>
</Target>
And my project references are invisible in Visual Studio Dependencies. Project compiles as intended, however.
I found out that <ItemGroup> with <PackageReference> inside target is respected, when the target is ran before CollectPackageReferences. However, I was unable to fill <ProjectReference> with any target, even the first one.
How does Visual Studio fill the Dependencies with solution projects?
I'm trying to use PhantomJS NuGet package in .NET core csproj application. But I think it is not possible using new PackageReference syntax for NuGet.
When I reference the PhantomJS package like this:
<PackageReference Include="PhantomJS" Version="2.1.1">
<IncludeAssets>all</IncludeAssets>
</PackageReference>
It does not do anything when I run dotnet build.
I'd expect it to copy the files inside PhantomJS package to the output directory (or anywhere in the project) so I could use the binary file provided by the PhantomJS package.
Is there another way to copy the contents of PhantomJS NuGet package to the output directory with MSBuild?
I think you want to use:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
in the main <PropertyGroup>, which causes all dependencies to be copied to the output folder. This means every single dependency gets copied though so this can be quite a mess in some situations.
If you then want to exclude specific assemblies or packages:
<ItemGroup>
<-- won't copy to output folder -->
<PackageReference Include="MahApps.Metro" version="1.6.5">
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
<PackageReference Include="Dragablz" version="0.0.3.203">
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
...
<-- normal will copy to output folder -->
<PackageReference Include="xmlrpcnet" version="3.0.0.266" />
<PackageReference Include="YamlDotNet" version="6.0.0" />
</ItemGroup>
<ItemGroup>
<!-- keep assembly reference from copying to output -->
<Reference Include="$(SolutionDir)MarkdownMonster\bin\$(Configuration)\$(TargetFramework)\MarkdownMonster.exe">
<Private>false</Private>
</Reference>
</ItemGroup>
compile in this context means they are available for compilation, but aren't copied to the output folder.
There are two solutions:
1:
<ItemGroup>
<PackageReference Include="PhantomJS" Version="1.0.8" GeneratePathProperty="true" />
</ItemGroup>
<Target Name="CopyPdfExe" AfterTargets="Build">
<Copy SourceFiles="(PkgPhantomJS)\tools\phantomjs\phantomjs.exe" DestinationFolder="$(OutDir)" />
</Target>
2:
<ItemGroup>
<PackageReference Include="PhantomJS" Version="1.0.8" GeneratePathProperty="true" />
</ItemGroup>
<ItemGroup>
<None Include="$(PkgPhantomJS)\tools\phantomjs\phantomjs.exe" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
prefer the #2 since if this project is referenced by another one, the .exe can also be copied to the output folder
The <PackageReference> syntax in NuGet uses transitive dependencies, just like the project.json syntax. As such, the same rules apply. See this NuGet v3 which talks about what does and doesn't work between packages.config and the newer syntax. Specifically
You cannot rely on install.ps1 or uninstall.ps1 to function. These files will execute when using packages.config, but will be ignored in v3. So your package needs to be usable without them running. Init.ps1 will still run on NuGet 3.
To get files to copy to the output directory, the PhantomJS NuGet package needs to be changed to use contentFiles.
The tag names are misleading. Try
<PackageReference Include="PhantomJS" Version="2.1.1">
<IncludeAssets>none</IncludeAssets>
</PackageReference>
or
<PackageReference Include="PhantomJS" Version="2.1.1">
<ExcludeAssets>all</ExcludeAssets>
</PackageReference>
instead in order to get the referenced assemblies and other files copied to the build output. See
https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files
Try dotnet publish
dotnet publish [<PROJECT>] [-c|--configuration] [-f|--framework] [--force] [--manifest] [--no-dependencies] [--no-restore] [-o|--output] [-r|--runtime] [--self-contained] [-v|--verbosity] [--version-suffix]
dotnet publish [-h|--help]
See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore2x
I know this is an old question, but what worked for me was to set IncludeAssets to "runtime"
Actually what is claimed to not work in the original question is what worked for me in .NET6:
<PackageReference Include="PhantomJS" Version="2.1.1">
<IncludeAssets>all</IncludeAssets>
</PackageReference>