Creating a basic NuGet Package - c#

I have a small c# library that wraps Dapper.net and I want to create a nuget package for this library. I've created a folder that contains the following:
Nuget-Package\
Nuget-Package\Package.nuspec
Nuget-Package\lib\
Nuget-Package\lib\DapperWrapper.dll
Here's the nuspec
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>GoDaddy.Data</id>
<version>1.0.0</version>
<authors>Owner Name</authors>
<owners>Owner Name</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>I provide a fast and slim layer between your code and stored procedures that your application needs to use. This layer provides more straight-forward access to procs than straight ADO and less overhead than using Entity or Linq. It currently uses Dapper.Net to do some of this work.</description>
<releaseNotes>Initial Release</releaseNotes>
<copyright>Copyright 2014</copyright>
<tags>ADO Dapper Proc "Stored Procedure"</tags>
<dependencies>
<dependency id="Dapper" version="1.13" />
</dependencies>
</metadata>
</package>
I then copy the resulting DapperWrapper1.0.0.0.nupkg over to my local nuget server.
After this I attempt to install it on a console application. I open a simple console application right click on references and say manage nuget packages. I find and select my package and select install and get the following error:
Attempting to resolve dependency 'Dapper (≥ 1.13)'.
External packages cannot depend on packages that target projects.
What am I doing wrong here?
Seems too simple to fail and yet I cant seem to find a good explanation of this error anywhere.

The answer can be found here.
http://www.marcusoft.net/2011/12/creating-tools-only-nuget-package.html
Apparently nuget wont resolve dependencies unless you have both "lib" and "content" folders even if you're not using them.
Wow that's a bug IMO.

See this nuget workitem: http://nuget.codeplex.com/workitem/595
You could try adding a files section to your nuget package, referencing the files in your project.

Related

c# nuget package doesn't show up in references in VS

I want to create a C# app that does things with the powershell. I found many solutions on the internet how to do that like this. The most answeres to this use the Powershell class from 'Microsoft.WSMan.Runtime'. Now when I search this package in nuget and install it, it doesnt show up in the references list in visual studio and also the using statement or the 'quick fix' on a PowerShell object doesnt find it.
Did I install something wrong or do I need something else too?
Edit for more infos:
.net Version 4.6.1
Tried 'Microsoft.WSMan.Runtime'v 7.0.0 and 7.0.3
'Microsoft.WSMan.Runtime' is downloaded and avaible at './packages/Microsoft.WSMan.Runtime.7.0.0'
'packages.config' does contain the entry for 'Microsoft.WSMan.Runtime'.
I found the assembly within the package targets .net core 3.1 instead of .net framework 4.6.1. So you can't see the reference in solution explorer.
It's by design of the package author, you can download the package manually, rename the name from xx.nupkg to xx.zip to check the content of the package.
The structure of the package:
And the content of the Microsoft.WSMan.Runtime.nuspec file:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
...
<dependencies>
<group targetFramework=".NETCoreApp3.1" />
</dependencies>
<contentFiles>
<files include="**/*" buildAction="None" copyToOutput="true" flatten="false" />
</contentFiles>
</metadata>
</package>

In VS2019 nuget doesn't consider referenced projects as lib, but as nuget packages

I'm using VS2019 community edition.
I have two .net core projects X, Y, X is referencing Y, and I want to package X as a Nuget package, I'm using the package feature in VS2019.
when I try to add X's Nuget package in another project it searches for Y as a Nuget package and not as DLL should be in X.
How can I change this so Y will be added as DLL in X's package?
I tried to add the following to X's project (.csproj):
<PropertyGroup>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
<ItemGroup>
<BuildOutputInPackage Include="#(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
But I still get the same result, nuget.exe tries to restore Y as Nuget package not as DLL comes with X's package.
UPDATE:
Also if Y has another Nuget dependency, it should be considered in X without referencing it directly in X.
I tried the following:
In X's project:
Go to Dependencies->Projects.
Right click on Y's project then Properties.
Set Private Assets to All
Now this will add Y's dll file in the lib folder in the X's nuspec file.
This will work fine if Y doesn't depend on any other Nuget packages that X doesn't know about, because those packages will not be mentioned as dependencies in X's nuspec file.
Finally I settled down on this:
Just reference Y, generate package for it too and live with it :'(
In VS2019 nuget doesn't consider referenced projects as lib, but as
nuget packages
Actually, the new nuget feature which you used and also PackagePath="lib" function will treat the dll as a nuget dependency rather than an assembly dll.
If you simply want Y to be an Assembly DLL rather than a nuget package, these methods won't work. I have tried these methods, and it really made me struggling.
After a deep research, I found that the problem is that dotnet pack will add the referenced project as a nuget pacakge into the main nuget package automatically. Because dotnet pack will automatically generates an Nuspec file to package the project according to its rules, which treat the referenced project as a Nuget package by default. You can open the X.nupkg file and will see like this under X.nuspec file:
However, in this pack mechanism, we do not have the right to change the rule.
Suggestion
1) when you create the X.nupkg file using Pack Button in VS2019, please do some changes to X.nupkg manually.
Use zip to open nuget compressed package, then open X.nuspec file and delete these node:
<dependencies>
<group targetFramework=".NETStandard2.0">
<dependency id="Y" version="1.0.0" exclude="Build,Analyzers" />
</group>
</dependencies>
Save the changes and then use the modified X.nupkg.
2) Or you should create a custom nuspec file based on our needs and rules manually to guidance the nuget pack process.
Try to use this nuspec file:
<?xml version="1.0"?>
<package >
<metadata>
<id>xxx</id>
<version>1.0.0</version>
<title>xx</title>
..................
</metadata>
<files>
<file src="bin\xxx\xxx\Y.dll" target="lib\xxx(targetframework)"/>
</files>
</package>
Also if Y has another Nuget dependency, it should be considered in X
without referencing it directly in X.
So far, Nuget does not have the feature to ask the main project whether to use the dependency package dll of the referenced project.
And the dependencies from the referenced projects always exist in the main project.
Besides, if you still want these, you could report these problems on our Team Forum and I hope the Team will check them carefully and give you a satisfactory reply.

How to package projects and used NuGet packages + files?

I'm working on a .NET Standard 2.0 project called ComputeSharp and I'm having some trouble creating a NuGet package from it. Some info:
The project only targets .NET Standard 2.0
The project uses 2 referenced projects in the same solution, each using some other NuGet packages. Here is a screen of my current solution.
One of the project, ComputeSharp.Shaders also references two .dll files, dxcompiler.dll and dxil.dll. These two are referenced by that project with the following snipped in its .csproj file. I made a PR to DotNetDxc with the update .dll files, so I'll no longer need to manually bundle the two .dll files into my project. So this is no longer an issue ✅
In the folder for the main ComputeSharp project, I also have a .nuspec file with the following structure, which also lists all the NuGet packages used by all 3 projects (note that the path for the *.mustache file goes up one directory because it's inside the ComputeSharp.Shaders project, and not the one from which I'm building the NuGet package, which is just ComputeSharp:
<?xml version="1.0"?>
<package >
<metadata>
<id>ComputeSharp</id>
...
<dependencies>
<dependency id="SharpDX.Direct3D12" version="4.2.1-beta0-gab36f12303" />
...
</dependencies>
<contentFiles>
<files include="..\ComputeSharp.Shaders\Renderer\Templates\*.mustache" buildAction="None" copyToOutput="true" />
</contentFiles>
</metadata>
</package>
In order to create the NuGet package, I first build ComputeSharp in Release mode, then open a cmd in the folder for that project, and run:
nuget pack ComputeSharp.csproj -Prop Configuration=Release -IncludeReferencedProjects
This does create a package that kinda looks ok. It contains the assemblies for all 3 projects, the two .dll files I use and the .mustache content file from the ComputeSharp.Shaders project.
Once uploaded to NuGet I can see the list of all the dependencies for the package, as you can see in this screen. So, that looks is ok as well.
PROBLEM: once I create a test project and install the NuGet package, I notice two things: first get this nice exception when I try to use any APIs, which makes me thing the other NuGet packages haven't been installed correctly at all, and then I can't find any of the APIs from either of those packages (eg. I don't see the SharpDX namespace at all), which makes me thing the previous point is probably correct. I have one last issue: the .mustache file (and relative parent folders) are not created in the build output directory, so I can't load it at runtime. I'm not sure why that is, since I did specify copyToOutputDirectory="true" in the .nuspec file.
I might be missing something obvious here, and I did check both the documentation and countless other SO questions on NuGet packages and whatnot, but I really couldn't figure out what I'm doing wrong here. I do have other NuGet packages uploaded, using the same method of including the referenced NuGet packages in the .nuspec file, and they work just fine when installed.
Thank you for your help!
EDIT #1: the indirect dependencies are now loaded correctly, so the last remaining issue is the content file not being copied to the build output directory (see changes above).
EDIT #2: closing this as it's too broad in scope, and the first part has been resolved already (.dll files and indirect package references). Opening a follow up question just for the issue about the content files not being copied here.

How to share source code via NuGet packages for use in .NET Core projects

I want to make small pieces of source code (e.g. helper classes) available for use in .NET Core projects (.csproj).
At this point I packaged the source code with NuGet in many different ways according to different blog posts and the official nuget docs. I used a nuspec file to control where my source files will end up in the nuget package, e.g.:
<files>
<file src="*.cs" target="content/LruCache" />
<file src="*.cs" target="contentFiles/cs/any/LruCache" />
</files>
I did not include any msbuild targets file or install script.
Whenever I install the NuGet package into a .NET Core project (https://learn.microsoft.com/en-us/dotnet/core/tools/csproj) I simply don't get anything there. No source files will be included into my project. I tried different settings for the <PackageReference/> node in the .csproj (PrivateAssets, etc.) without success.
Is it meant to be possible at all? If so, how should it be done?
Background:
The reason for doing this is some kind of diamond problem where we have projects B and C both using helper class A and a third project D using B and C.
In this situation I don't want to deal with assembly version conflicts when different (incompatible) versions of A have been used in B and C.
Is it meant to be possible at all? If so, how should it be done?
The answer is yes. Since you test project type is .net core. You should use contentFiles instead of content. content is used for packages.config. Check the Using the contentFiles element for content files and blog NuGet ContentFiles Demystified for more details.
So your .nuspec file should be:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MyTestCore</id>
<version>5.0.0</version>
<authors>TestContentFile</authors>
<owners>TestContentFile</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package Description</description>
<contentFiles>
<files include="any/any/Test.cs" buildAction="content" flatten="true" copyToOutput="true"/>
</contentFiles>
</metadata>
<files>
<file src="contentFiles/any/any/Test.cs" target="contentFiles/any/any/LruCache" />
</files>
</package>
The nuget package should look like:
Note: When you create a new package, do not forgot to remove the nuget cache for this package in the C:\Users\<UserName>\.nuget\packages folder, otherwise, it always install the old package.
With this method, the source files will be included into your project.
Hope this helps.

NuGet package with a single class as source code

I have a simple class I like to use when I do unit tests. I'd like to create a NuGet package so I can easily use it and spread out updates between my solutions.
Will I have to create an assembly of it, or is it possible to create a NuGet package which contains just a source file which is then compiled together with everything else? If so, how would you configure that package?
If you want to create a package with just a source code file, it is trivial to do. For more explanation, see this blog post.
First of all, create your code file, and save it as (for example) myFile.cs.pp (note the pp (pre-processor) extension.
You can do some pre-processing on the file for things like namespace. To add a namespace of .MySubNameSpace, change the declaration in your code file to be
namespace $rootnamespace$.MySubNameSpace
Add this file to the content section of the nuget package.
Build the package, and you're all set.
Your .nupec package file would then look something like the following.
<?xml version="1.0" encoding="utf-16"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MyPackageName</id>
<version>1.0.0</version>
<title>My Package Name</title>
<authors>Your Name</authors>
<owners />
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My package description.</description>
</metadata>
<files>
<file src="content\myCodeFile.cs.pp" target="content\myCodeFile.cs.pp" />
</files>
</package>
You can do all of this through the NuGet Package Explorer.
EDIT: As other answers have said, NuGet can allow you to distribute simple source codes. However, I would strongly recommend that you take the more mainstream approach of just providing an assembly. NuGet makes it pretty quick to do so - you'll have to go through the "pain" of creating a separate project for this one source file, and create a package for that assembly, but it's all pretty simple.
This has the additional benefit that when you (nearly inevitably) want to add more types, it won't give any problems to the projects depending on it.
Simply use the content folder as referenced here Nuspec Reference (look for the 'Content Files' section)
<file src="css\mobile\*.css" target="content\css\mobile" />

Categories

Resources