Creating a Class Library
Explore how to create reusable class libraries in C#, set up solutions in Visual Studio, and reference libraries in console applications. Understand handling command line arguments, using essential .NET CLI commands, managing dependencies, and implementing unit testing with xUnit. Learn troubleshooting tips and maintaining code formatting for consistent project development.
Class library projects do not contain a Main method because a library is not an executable. It cannot run on its own but can be referenced and used inside other projects.
Setting up the solution
Let’s create and use a class library in Visual Studio.
First, we create a console application that serves as our executable. After creation, the environment looks similar to the following:
Right-click the “Solution” node in the “Solution Explorer” and click “Add” and then “New Project”.
Select “Class library” as the project type and complete the setup wizard.
Our solution now contains two projects.
Next, we replace the default code in the class library with an Employee class.
Line 1: We define a file-scoped namespace called
EmployeeDirectory.Lines 5–6: We define public fields to store the employee’s name.
Lines 8–12: We create a constructor to initialize the fields when a new
Employeeobject is instantiated.Lines 14–17: We define a method to print the employee’s full name to the console.
Referencing the library
To use our new class library, we must reference it from the consuming project.
Right-click the “Dependencies” node inside the console project and click “Add Project Reference”.
From the list, check the class library project and click “OK”:
The using directive allows us to import the class library's namespace and access its classes. We update the Program.cs file in our console application to look like this:
Line 1: We import the
EmployeeDirectorynamespace from our referenced class library.Line 3: Using top-level statements, we instantiate a new
Employeeobject.Line 4: We call the
PrintFullNamemethod, which executes the code defined in the library.
Handling C# command line arguments
When building a library, it is important to remember that the library itself does not have an entry point. However, it often provides the logic for processing data received from the terminal.
In a typical workflow, the consuming console application receives C# command line arguments through its string[] args parameter. It then passes those arguments into the class library's methods or constructors to drive the application's behavior.
For example, if you want to create an employee based on a name passed via the terminal:
// In Program.csif (args.Length > 0){// Passing c# command line arguments into the library classvar emp = new Employee(args[0], "External");emp.PrintFullName();}
CLI commands recap
The .NET CLI is the primary tool for developing applications without a graphical IDE. Here are the essential commands we use daily:
dotnet new <template>: Creates a new project from a template. For example, we usedotnet new consolefor a console application ordotnet new xunitfor a test project.dotnet build: Compiles the application and its dependencies.dotnet run: Builds and executes the application in one step.dotnet test: Executes unit tests within the project.dotnet publish: Compiles the application and publishes the output for cloud or local deployment.
Managing dependencies and NuGet restore
To add third-party libraries to our projects, we use the add package command:
dotnet add package Newtonsoft.Json
This command download the specified package and add it to our project dependencies.
When we clone a project from source control, it does not include the downloaded packages. We must restore them using the dotnet restore command. Modern commands like build and run trigger this restoration implicitly. Running it manually is still common in continuous integration pipelines.
Unit testing with xUnit
Testing is a core part of modern development. We can create a test project using the dotnet new xunit command. Inside, we write test methods decorated with the [Fact] attribute:
using Xunit;namespace MathTests;public class CalculatorTests{[Fact]public void Addition_ShouldReturnCorrectSum(){int result = 2 + 2;Assert.Equal(4, result);}}
Line 1: We import the xUnit testing framework.
Line 3: We declare a file-scoped namespace.
Line 7: We mark the method as a test case using the
Factattribute.Line 10: We define the logic being tested.
Line 11: We verify that the actual result matches our expected result.
Troubleshooting and code formatting
If a project behaves unexpectedly or fails to compile after switching git branches, we can often resolve the issue by deleting the generated bin and obj folders. Running dotnet clean also helps clear cached build outputs.
Finally, to maintain a consistent code style across our team, we can use the built-in formatter:
dotnet format
This command scans our project and automatically fixes styling and indentation issues.