NuGet: package with source code that can be referenced as library - c#

Is there any possibility to create a NuGet package containing the source code that can be referenced as library?
When I use the .nuspec for packing the created .nupkg contains the source code but cannot be referenced. I have already tried out to add a library node within the .nuspec as some suggested on SO but the resulting .nuspec does not match the standard and thus cannot be created.
When using .csproj for packing the .nupkg does only contain the .dll. It can be referenced but cannot be debugged because it does not contain any source code.
How could I achieve both? A referanceable library that contains source code.
In advance thank you for your time.

Here's a .nuspec file I use to package sources from multiple directories that get used as a library in other projects:
<?xml version="1.0"?>
<package >
<metadata>
<id>Your.Package</id>
<version>1.0.14</version>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Class library.</description>
<releaseNotes>Initial release.</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>some tags</tags>
</metadata>
<files>
<file src="*.cs" target="content/App_Packages/<YourPackage>.Sources" />
<file src="Configuration/*.cs" target="content/App_Packages/<YourPackage>.Sources" />
</files>
</package>
Just change the "file" tags to reference the files you're trying to include.
When you're ready to create the .nupkg file, cd to the directory containing your .nuspec file and run:
nuget pack .nuspec

There's now the csproj tag EmbedAllSources. What that does is embed your source code into your NuGet package.
Usage is like this:
<EmbedAllSources>True</EmbedAllSources>
Embedding the source code will allow people to, for example, navigate to your method definitions and see the code just the way you've written it, as opposed to, not being able to navigate to definitions, at all, or rely on decompiled code.
Adding the debug symbols to the above will allow your users to put breakpoints in your code and step through it during debugging.
If that is what you want, add this to your csproj:
<DebugType>Embedded</DebugType>
<EmbedAllSources>True</EmbedAllSources>

Related

nuget: package version is not being updated

I'm trying to pack a new version of a custom NuGet package and when I use the pack command I'm getting a .nupkg file which has a version number that doesn't match with the one that I've specified in the .nuspec file.
Example:
nuget pack mypackage.csproj -IncludeReferencedProjects -Prop Configuration=Release
.nuspec file:
<?xml version="1.0"?>
<package >
<metadata>
<id>mypackage</id>
<version>1.0.1</version>
<authors>me</authors>
<owners>me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>blah</description>
<releaseNotes></releaseNotes>
<copyright>Copyright 2016</copyright>
<tags>tag1 tag2</tags>
<dependencies>
</dependencies>
</metadata>
</package>
I should get a file named mypackage.1.0.1.nupkg, but I'm getting a file named mypackage.1.0.0.nupkg instead
I'm also getting the same result when I try to pack it by using the AssemblyInfo data included in the Properties\AssemblyInfo.cs and declaring the version as a variable in the .nuspec file:
Properties\AssemblyInfo.cs
...
[assembly: AssemblyVersion("1.0.1")]
...
Should I look for another properties in my project to update my NuGet package?
SOLUTION: Ignored the .nuspec file and managed the package versions via .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net451;net452</TargetFrameworks>
...
<AssemblyVersion>1.2.1</AssemblyVersion>
</Project>
Thanks in advance!
Make sure to change both the Assembly Version and File Version in Project Properties > Application > Assembly Information.
After that make sure you are set to Release mode and build your project.
Execute the Nuget Spec command in your project's folder
Edit the Spec, version should be set to $version$ so as to grab it from your project, remove the lines that need removing, fill the ones with placeholders.
Execute your Nuget Pack command in the same folder and you should be good.
I often forget to build my project so it doesn't update the version.
I fell foul of this recent as well.
You need to use the Properties\AssemblyFileVersion attribute to set the correct value for a nuget package
[assembly: AssemblyFileVersion("1.0.1")]
Well, I've finally managed to update my version by packing using the AssemblyInfo version. It seems like my publishing process for this package is completely ignoring the .nuspec file and gets the version from the last compiled source.

Content files auto included by Nuget

The structure of my folder & source codes.
Areas/**/*.cshtml
Views/**/*.cshtml
And those cshtml files were compiled into dlls by generators. So that it does not need to be included into nuget packages. (Only the dll is needed)
So the Nuspec file will be like this.
<files>
</files>
Now I want to include additional dlls into Nuget packages.
So i added the following the Nuspec file
<files>
<file src="bin\Release\**\xxxxx.dll" target="lib\net451" />
</files>
But this will bring the *.cshtml files into nuget packages.
Is there any way that i could exclude those files?
Thanx!
Thanx to #rohit21agrawal and #jainaashish.
I create an issue in github
https://github.com/NuGet/Home/issues/6265
If you are packing your csproj with a .nuspec next to it, then the content files from your project will be added if one of the condition is met:
There is no nuspec file
There is a nuspec file but no files node.
There is a nuspec file with non-empty files node.
The only way to prevent content files from your project to be added into the package is to specify an empty files node.

Providing a code analysis ruleset to a .net core project through NuGet

I've run into a problem when upgrading a .NET 4.6 project to .NET Core 2.0. All our projects use a custom StyleCop ruleset which is provided by a NuGet package. The ruleset is in a file called custom.ruleset and lives in the content folder inside the package. All our projects consume this package and so get a copy of custom.ruleset.
However, in Core 2.0 and Standard 2.0 projects this doesn't work. Files are no longer copied from the content folder of a package, and we're told to use the contentFiles folder instead.
I have a nuspec that now looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<version>1.0.11</version>
<metadata>
...
<contentFiles>
<files include="content\*.ruleset" buildAction="None" copyToOutput="false" flatten="true"/>
</contentFiles>
</metadata>
<files>
<file src="content\**" target="contentFiles/any/any" />
</files>
</package>
With this structure the ruleset appears in Visual Studio under the project, but trying to reference it from the project's .csproj file with <CodeAnalysisRuleSet>custom.ruleset</CodeAnalysisRuleSet> silently fails and reverts to using the default ruleset. I can force it to work by adding <CodeAnalysisRuleSet>$(NuGetPackageRoot)CustomRuleset\1.0.11\contentFiles\any\any\custom.ruleset</CodeAnalysisRuleSet> but this means the csproj will need updating whenever the ruleset changes, so it may as well be a manual process. Any ideas how to fix this?
The idea is to not try to deploy the file as content but add build logic to the NuGet package.
Make sure that the package is structured in the following way:
build\
build\custom.ruleset
build\{YourPackageName}.targets (e.g. CustomRuleset.targets)
This structure causes the .targets file to be automatically imported into the consuming project by convention.
The .targets file should then contain:
<Project>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)custom.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>
This will cause the project's ruleset property to be overwritten to the location relative to the .targets file.
Note that this also applies to .net framework projects using the new PackageReference style of NuGet packages (replacement of packages.config) which is opt-in in VS 2017 (15.2+).

How to inherit referenced assemblies in NuGet package

Simple question. I have a NuGet package project. This project references other class library projects (they are not NuGet Packages). I would like my NuGet package to load its references DLL's into the project installing the package. Is this possible, or do all my referenced class libraries need to be NuGet packages in order to specify them as dependencies?
TIA
When performing a nuget pack command, you can specify the option IncludeReferencedProjects.
From the docs:
Indicates that the built package should include referenced projects either as dependencies or as part of the package. If a referenced project has a corresponding .nuspec file that has the same name as the project, then that referenced project is added as a dependency. Otherwise, the referenced project is added as part of the package.
You can add your referenced dlls as files to nuspec and can set immediately source path file and target path file inside a nuget package. Next you should add references to this files in nuspec. It looks like this (I removed other metadatas):
.nuspec
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
...
<references>
<reference file="First.dll" />
<reference file="Second.dll" />
</references>
</metadata>
<files>
<file src="SomePath\First.dll" target="lib\First.dll" />
<file src="SomePath\Second.dll" target="lib\Second.dll" />
</files>
</package>

NuGet: Don't include reference from package

Summary
When I package a library using NuGet and reference it in another project the referring project will pull additonal files in to the build directory.
Working Case
Project: ReferenceLibrary
Output: ReferenceLibrary.dll
Project: DerivedLibrary
Output: DerivedLibrary.dll
References: ReferenceLibrary (Copy Local = False)
Project: ConsoleApplication
Output: ConsoleApplication.exe
References: DerivedLibrary
Edit: The reference library is not copied because it is resolved at runtime. There's several versions depending on the target. The reference in derive proj. is so I can code against it.
If I build this then only DerivedLibrary.dll is copied to the ConsoleApplication build folder (i.e. bin/Release).
Non-working Case
Project: ConsoleApplication
Output: ConsoleApplication.exe
Package: DerivedLibrary.nupkg (depends on ReferenceLibrary.nupkg)
A project reference is added to DerivedLibray.dll. Both DerivedLibrary.dll and the ReferenceLibrary.dll are copied from their packages.
I can see it being copied in the MSBUILD log.
_CopyFilesMarkedCopyLocal:
Copying file from "c:\...\ReferenceLibrary.dll" to "bin\Debug\ReferenceLibrary.dll"
Even though it's not referenced in the .csproj anywhere.
I can't tell if this is a NuGet problem (due to how it unpacks things) or a Visual Studio project (how it copies referenced assemblies and encodes the requirements in other assemblies).
A possible solution I've found is to use a post build target to delete the offending references.
In the derived library add a DerivedLibrary.targets file.
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="RemoveUnwantedReferences" AfterTargets="Build">
<Message Text="Removing unwanted references"/>
<Delete Files="$(OutputPath)ReferenceLibrary.dll"/>
</Target>
</Project>
Then in the .nuspec include it
<package>
...
<files>
<file src="Targets/DerivedLibrary.targets" target="/build/DerivedLibrary.targets" />
</files>
</package>
Then when someone installs the package the post build hook will be added. When they build the files that are copied will then be deleted automatically.

Categories