CSharp.Mongo.Migrations
Building and Releasing an Open-source Library using .NET & GitHub
Open-source libraries are a major part of developing software, whether consuming them as libraries through a package manager, interacting with other developers, or contributing back to the community, there aren’t many projects or organisations that don’t rely on open-source software.
This article will cover the basics of getting started with library development in .NET and GitHub using the CSharp.Mongo.Migration library as an example.
Setting Up a Repository (with GitHub)
In software development, version control is a must. Sharing, collaboration, and discussion are all large parts of open-source software development. GitHub is a great (and free, for public repositories) tool to manage:
- Code with git
- Documentation through wikis
- Issue tracking and discussion
- Simple kanban style project management
- CI/CD
Creating the Repository
In order to get started with a new GitHub repository we'll need to sign up for an account (or use an existing one).
Decisions
There are a number of decisions that should be made before getting started on an open-source library:
- Name: this is the user visible name of the repository, and therefore library or project, in .NET this might be the solution name, or root project namespace
- Open-source licence: This licence will help to protect the project from unfair use, see https://choosealicense.com/ for the basics on selecting a licence
Givens
There are some assumed settings for a new open-source, .NET repository:
- Visibility: This should be public, otherwise we aren’t really building an open library!
- Readme: All public libraries should have a helpful README.md file, here's an example
- gitignore: ‘Visual Studio’ is the default ignore file for .NET projects
- Licence: As mentioned above, it's best to include a LICENSE file in the repository root, here's an example
Configuring the Repository
Consider enabling the following extra features for the repository:
- Wikis: Consider adding a wiki to document the library.
- Issues: Allows viewers or collaborators to log bugs, or raise ideas for the library implementation.
- Projects: Collaborators can view issues in a kanban board and track progress of milestones.
Cloning the Repository
Now that we have a repository on GitHub with a few of the default files we'll need to initialise a local clone of the source.
Make sure to install and configure git
and add an SSH key to GitHub before attempting to clone the repository.
The easiest way to clone a repository is to visit the repository page on GitHub, click the 'Code' button, copy the repository URL, and run the git clone
command in a terminal:
mkdir ~/dev
cd ~/dev
git clone git@github.com:JordanDChappell/CSharp.Mongo.Migration.git
cd CSharp.Mongo.Migration
Getting Started With .NET
.NET is a free and open-source cross-platform framework supported by Microsoft where most applications are written in the C# programming language. The platform can be used to build web and desktop applications, as well as command line utilities, services, and class libraries.
Prerequisites
Before diving in we will need the following:
- .NET SDK
- A code editor or IDE:
Creating the Project
The .NET SDK includes a large variety of different project templates that can be viewed here or by running dotnet new list
from a terminal.
Most .NET projects (especially those that are developed using the Visual Studio IDE) include a solution (sln
) file and one or more project files (csproj
) to organise all of the code and configuration.
We'll be using the sln
and classlib
templates to create a library with the same name as our repository on GitHub:
cd ~/dev/CSharp.Mongo.Migration
dotnet new sln
dotnet new classlib
dotnet sln ./CSharp.Mongo.Migration.sln add ./CSharp.Mongo.Migration.csproj
The solution and project will be named based on the directory that you run the command from, or can be set explicitly using the --name argument.
If you followed along exactly as described above the project will have the following folder structure:
~/
├─ dev/
│ ├─ CSharp.Mongo.Migration/
│ │ ├─ .git/
│ │ ├─ obj/
| | ├─ .gitignore
│ │ ├─ Class1.cs
│ │ ├─ CSharp.Mongo.Migration.csproj
│ │ ├─ CSharp.Mongo.Migration.sln
| | ├─ LICENSE
| | ├─ README.md
This structure would be perfectly fine for a very small library with a tiny number of code (cs
) and other files, but may become unorganised as the library grows. I suggest that we create the following directory structure instead with a few simple rules:
- Code should be placed in the
src/
directory - C# projects should be placed in their own named directories under the
src/
directory - Other IDE and configuration content that does not relate to the source should be in the root of the repository
- E.g. directories like
.vscode/
for IDE config, or.github/
for workflows and actions
- E.g. directories like
~/
├─ dev/
│ ├─ CSharp.Mongo.Migration/
│ │ ├─ .git/
│ │ ├─ src/
│ │ │ ├─ CSharp.Mongo.Migration/
│ │ │ │ ├─ obj/
│ │ │ │ ├─ Class1.cs
│ │ │ │ ├─ CSharp.Mongo.Migration.csproj
│ │ ├─ .gitignore
│ │ ├─ CSharp.Mongo.Migration.sln
│ │ ├─ LICENSE
│ │ ├─ README.md
Note: you will need to update your solution references if you manually move the CSharp.Mongo.Migration
project directory.
Testing in .NET
It's pretty important for any software project to include a variety of different kinds of automated or manual test processes. When creating something open-source, automated tests that gate PRs and releases can help to reduce problems or issues in the library.
Test Libraries
There are three main testing libraries that are recommended in the .NET ecosystem:
In this example, we'll be using xUnit
as the library for writing and running tests as well as AutoMoqCore for simple dependency mocking in our tests.
Creating a Test Project
As before, the .NET SDK includes a template for unit test projects, and specifically, one for xUnit
. Let's create a new project directory and unit test project in our codebase and link the required project and solution files:
mkdir ~/dev/CSharp.Mongo.Migration/src/CSharp.Mongo.Migration.Test
cd ~/dev/CSharp.Mongo.Migration/src/CSharp.Mongo.Migration.Test
dotnet new xunit
dotnet sln ../../CSharp.Mongo.Migration.sln add ./CSharp.Mongo.Migration.Test.csproj
dotnet add ./CSharp.Mongo.Migration.Test.csproj project ../CSharp.Mongo.Migration/CSharp.Mongo.Migration.csproj