Celebrating one million downloads on NuGet
My open source projects have recently ticked over 1 million downloads on NuGet. This post gives a quick overview of my most popular projects.

My open source side projects have recently ticked over the 1 million download milestone on NuGet. I'm pretty happy about that, as I don't have many opportunities to do open source work in my day job, so it's purely "side project" territory for me.

To mark this milestone, I've written a brief overview of my four most popular projects:

DeviceId (my most popular project, by far)

A library providing functionality to generate a 'device ID' (or hardware fingerprint) that can be used to uniquely identify a computer. It has a very simple API but can do some pretty complicated stuff in order to generate a unique identifier for the computer.

Example #1: A really simple device ID using the machine name, MAC address, and a token stored in a file.

string deviceId = new DeviceIdBuilder()

Example #2: A more complex device ID that works cross-platform:

string deviceId = new DeviceIdBuilder()
    .OnWindows(windows => windows
    .OnLinux(linux => linux
    .OnMac(mac => mac


A library providing JSON formatting and pretty printing functionality for .NET. This was originally based on Mark Rogers' work on JsonPrettyPrinterPlus, but I added support for a wider range of .NET versions, as well as some extra 'quality of life' changes (such as JSON minification).

Example #1: Pretty-printing a JSON string:

string formattedJson = JsonFormatter.Format(unformattedJson);

Example #2: Minifying a JSON string:

string minifiedJson = JsonFormatter.Minify(json);


Provides a fluent-interface for building runtime-customizable implementations of ICustomTypeDescriptor. Very useful for binding to property grids, for example.

Example #1: Creating a descriptor from an object.

var instanceToBind = new ExampleClass();

var descriptor = DynamicDescriptor.CreateFromInstance(instanceToBind);

descriptor.GetDynamicProperty(nameof(instanceToBind.Property1)) // Get the property using its name.
    .SetDisplayName("Property #1")
    .SetDescription("The first property")
    .SetCategory("Example category")

descriptor.GetDynamicProperty((ExampleClass x) => x.Property2) // Get the property using an expression.
    .SetDisplayName("Property #2")
    .SetDescription("The second property")
    .SetCategory("Example category")

propertyGrid.SelectedObject = descriptor;

Example 2: Creating a descriptor from a dictionary.

var data = new Dictionary<string, object>();
data["Property1"] = "hello";
data["Property2"] = "world";

var descriptor = DynamicDescriptor.CreateFromDictionary(data);


A very simple library that exposes some functionality for encoding/decoding integers and strings using basic bijective functions.

Example #1: Encode an integer as a string.

string encoded = Bijective.Encode(1234, Alphabet.Base62); // returns "n8i12F"

Example 2: Decode a string value to an integer.

int decoded = Bijective.Decode("n8i12F", Alphabet.Base62); // returns 1234

Has Base16, Base26, Base52, Base58, and Base62 alphabets out of the box, and can use any custom alphabet. Note that this library uses a generic one-size-fits-all naive encoding algorithm, so it won't be anywhere near as fast as a proper custom algorithm devised for a specific encoding.

Posted by Matthew King on 14 December 2022
Permission is granted to use all code snippets under CC BY-SA 3.0 (just like StackOverflow), or the MIT license - your choice!
If you enjoyed this post, and you want to show your appreciation, you can buy me a beverage on Ko-fi or Stripe