Framework with nuget support

I thought about building some small framework. The plan would be to build some libs with some helper classes. For example a lib for my camera classes which I can then use especially in my prototype projects. The idea of having the libs available as nugets is nice since I could do some prototyping in less time and also do it on machines where I don‘t have my code base directly available.

Since many here in the community are already using nugets for doing similar things and code distribution I thought I ask here for some guideline / workflow / best practise / advice.

I will describe where I am at the moment:
As a test I created a camera library / nuget with the project name Kwyrky.MyFramework.Camera with a simple Camera2D class as a starting point. The base namespace is be the same as the project name, so Kwyrky.MyFramework.Camera in this case. Is the naming of the project and namespace good here or should I consider to name it different? MonoGame.Kwyrky.MyFramework.Camera?

I read there are SDK-style projects and non-SDK-style projects. I think at this point MonoGame in the current version uses / provides the older non-SDK-style project templates? I guess this will be changed in future updates of MonoGame? Will this be an issue if I want to update my libs / nugets to newer MonoGame versions in the future? Just asking because updating library projects manually is something I want to avoid if possible. Anyway I think in both SDK-style projects and non-SDK-style projects it is possible to configure the nuget metadata in different places:

  1. Visual Studio - project properties - package
  2. In a *.nuspec file
  3. As parameters when using the dotnet pack command

I tried using nuget CLI first and I could create a nuspec file using the nuget spec command.

NUSPEC FILE:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>Kwyrky.MyFramework.Camera</id>
    <version>1.0.0</version>
    <title>Kwyrky.MyFramework.Camera</title>
    <authors>Kwyrky</authors>
    <description>Cameras for MonoGame.</description>
    <tags>MonoGame Kwyrky Camera</tags>
    <dependencies>
      <group targetFramework="net6.0" />
    </dependencies>
  </metadata>
</package>

If on Windows and Visual Studio is available everything is also configurable in the project properties in the package section.

I tried to do the packaging also using the nuget CLI tool but it did only work using the dotnet CLI tool. Iirc it was because nuget can not handle non-SDK-style projects?
It is possible to provide all metadata also with the dotnet pack command directly which will also overwrite the settings made in a nuspec file if one is present. I think I will use method 3. in the future since I can then also create packages on linux where there is no Visual Studio available and also avoid creating a nuspec file.

DOTNET PACK AND PUSH COMMANDS:

dotnet pack -c Release /p:PackageId="Kwyrky.MyFramework.Camera" /p:Version="1.0.0" /p:Title="Kwyrky MyFramework Camera" /p:Authors="Kwyrky" /p:Description="Cameras for MonoGame." /p:PackageTags="MonoGame Kwyrky Camera" /p:PackageIcon="icon.png" /p:PackageOutputPath="H:\Dev\0001\LocalNugetFeed"

The icon file icon.png (128x128 as size is recommended and format can be either png or jpg with transparency) in this case has to be placed in the project root directory (where the csproj file is). The parameter PackageIcon specifies the path to the icon file inside the finished nuget package. To get the icon into the package it needs to be added by adding an ItemGroup entry to the csproj file like this:

  <ItemGroup>
    <None Update="icon.png" Pack="true" PackagePath="" />
  </ItemGroup>
dotnet pack -c Release
dotnet pack -c Release /p:PackageOutputPath="H:\Dev\0001\LocalNugetFeed"

NOTE: The PackageOutputPath parameter will put the nuget directly into my local nuget feed. I save running a second command this way which would be something like:

dotnet nuget push ".\bin\Release\Kwyrky.MyFramework.Camera.1.0.0.nupkg" -s "H:/Dev/0001/LocalNugetFeed"
dotnet nuget push ".\bin\Release\Kwyrky.MyFramework.Camera.1.0.0.nupkg" --source "H:/Dev/0001/LocalNugetFeed"

When pushing to nuget.org instead of a local feed later I think I will need an API Key for authentication which I can provide like this:

dotnet nuget push ".\bin\Release\Kwyrky.MyFramework.Camera.1.0.0.nupkg" -s "nuget.org" -k "<your-api-key>"
dotnet nuget push ".\bin\Release\Kwyrky.MyFramework.Camera.1.0.0.nupkg" -k "<your-api-key>"

LOCAL NUGET FEED COMMANDS:
For testing I am using a local nuget feed which in my case is just a simple folder and using the folder name as the feed name:

dotnet nuget add source "H:\Dev\0001\LocalNugetFeed" -n LocalNugetFeed
dotnet nuget add source "H:\Dev\0001\LocalNugetFeed" --name LocalNugetFeed

After adding a local nuget feed it should show up when running this command which lists all available nuget sources:

dotnet nuget list source
Registered Sources:
  1.  nuget.org [Enabled]
      https://api.nuget.org/v3/index.json
  2.  LocalNugetFeed [Enabled]
      H:\Dev\0001\LocalNugetFeed
  3.  Microsoft Visual Studio Offline Packages [Enabled]
      C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\

To later add a nuget to a new project where you want to use it:

dotnet add package "Kwyrky.MyFramework.Camera" --version "1.0.0" --source "H:\Dev\0001\LocalNugetFeed"

This Microsoft article covers assembly naming, which is by default the name of the project.

This Microsoft article covers Namespace naming guidelines.

You can check how I do my libraries for example: https://github.com/Apostolique/Apos.Input

I made some templates to create libraries faster:

dotnet new install Apos.Framework.Library.CSharp
dotnet new aposframeworklibrary -o Kwyrky.MyFramework.Camera --repo https://github.com/Kwyrky/Kwyrky.MyFramework.Camera --branch main --description "Camera library for MonoGame." --param:author "Kwyrky"

Fill in your own info in the second command. More info: https://github.com/Apostolique/Apos.Framework/tree/main/Source/Library

1 Like

Just reading your post and you seem to be doing a lot with command line calls.

Ill post on what i do for my packages later, but i just put all my description, icon, version etc. Info in the project file.

I then just right click the project and select pack. This gives me a nuget package i can then run one command line to push that up (put mine it batch files at the min)

And up they go :slight_smile:

I also have templates now that will set up a base monogame project with my packages so its ready to go with scene management, audio and basic UI. These templates are also nuget packages too.

1 Like

That is a nice idea, that makes everything faster when trying out some stuff.

1 Like

I still need to learn how to create dotnet templates. Did you write something yourself for scene management? There was an old sample for scene management which had transitions but maybe something very simple is good enough.

Yes, i have my own scene manager. Ill try and get some time today (doubtfull work is mad at the min) and put down my steps.

Might be a worthy blog post maybe?

1 Like

Take your time I have very little time myself. So no problem of it takes a while. So now that I basically know how to package libraries as nugets I can go back to the code and just try to write / improve something simple as the mentioned 2D Camera.

1 Like

Just posting this here, so I remember to do this :slight_smile:

Sorry it’s taking me so long to find the time.

OK, so, this is how I create and publish my nuget pacakges, I am sure there is a much better work flow, but this works for me, happy to hear a better way of doing it :smiley:

I have a number of assemblies I have published. In the project of the assembly I want to publish I set the versions, auththors, project url, description and icon url like so:

When I want to push a new version up, I right click the project and click the “Pack” Option

This then creates the *.nupkg that can now be puhed to NuGet

I can then run my cmd file with my Nuget credentials and the package location, and it then goes up (if there is not an existing version there) onto NuGet ready to be consumed. It can sometimes take a while for it to sync up, but never more than a few minutes.

nuget.exe push -Source "<YourSource>"  -ApiKey <YourNuGetApiKey> "<location of pakage>.nupkg"

Templates are a little different as I have bundled my together
image

I create the projects first, then once they are how I want them I add them to a TemplatePackage:-

I can then pack and publish like another assembly as above.

Oh, here is my template project file too :slight_smile:

Hope this helps, rushed it a bit, not looked at this in a while, juse use it now, hope I have not missed anything out, as I say this is how I do it, I am sure there are better ways :smiley: