Assemblies and DLLs in .NET Core

When you build a .NET application, your source code is transformed into a structured, deployable unit known as an assembly. Assemblies are the backbone of .NET execution — they package compiled code, metadata, and resources so the runtime can load and run applications efficiently.

Whether you are building a small console tool or a large distributed system, assemblies enable modular design, code reuse, and predictable deployment.


What Is an Assembly?

An assembly is the compiled output produced when a .NET project is built. It acts as the smallest unit of deployment and versioning in the .NET ecosystem.

In practical terms: An assembly is a self-contained package that the runtime can load, verify, and execute.

Assemblies typically exist in two forms:
  • Executable (.exe) — launches an application
  • Library (.dll) — provides reusable functionality
Despite the difference in usage, both share the same internal structure.

What Is an Assembly?

A Dynamic Link Library (DLL) is a compiled file that contains reusable code and functionality which multiple applications can use without needing to duplicate that code. Instead of building the same features repeatedly inside every application, developers package common logic into a DLL and reference it wherever needed.

Example Scenario:

Imagine a company building several systems:
  • A web portal
  • A mobile API
  • An internal admin tool

Each requires payment processing.

Instead of rewriting the logic three times, the team creates:

PaymentProcessor.dll

Change the DLL once — improvements propagate everywhere. This is a cornerstone of professional software design.

Example: Imagine several applications need tax calculation logic.

Instead of rewriting it everywhere, a developer creates a library:

Step 1 — Create the Class Library

dotnet new classlib -n FinanceUtilities

Step 2 — Add the Tax Calculator

Open the generated class file and replace it with:


namespace FinanceUtilities
{
    public class TaxCalculator
    {
        public double Calculate(double amount)
        {
            return amount * 0.18;
        }
    }
}
Now build the project:

dotnet build

Output: FinanceUtilities.dll

Your reusable library is ready.


Step 3 — Create an Application That Uses the DLL

Now create a console app:


dotnet new console -n FinanceApp

Step 4 — Add Reference to the DLL Project

Navigate to the console project and run:


dotnet add reference ../FinanceUtilities/FinanceUtilities.csproj

Now the app can access the library.


Step 5 — Use the DLL in Code

Open Program.cs:


using FinanceUtilities;

class Program
{
    static void Main()
    {
        var calculator = new TaxCalculator();
        double tax = calculator.Calculate(1000);

        Console.WriteLine($"Tax: {tax}");
    }
}
Run it:

dotnet run
Output:

Tax: 180

Your DLL is now being consumed successfully.

Note: By default, the assembly name matches the project name, which is why building the FinanceUtilities project produces FinanceUtilities.dll.


What Is an EXE?

An EXE is a runnable assembly that contains an entry point (Main) and starts program execution.

Example:

static void Main(string[] args)
{
    Console.WriteLine("Application started");
}

An executable (EXE) in .NET is created by building an application project — such as a console, desktop, or web app — that contains an entry point (Main method) where execution begins. When you run dotnet build on this project, the compiler generates an EXE that acts as a host to start the .NET runtime and execute your application.

Key points:
  • EXE is produced from runnable project types (not class libraries).
  • it contains the application entry point
  • it loads dependent DLLs at runtime
  • it serves as the startup file that the operating system executes.

EXE vs DLL — Key Differences

EXE DLL
Runnable application Reusable library
Has an entry point (Main()) No direct entry point
Launched directly by the operating system Loaded by the runtime or another application
Starts program execution Supports execution by providing shared functionality

Unlike a DLL, which holds reusable code, the EXE is responsible for launching the program and loading any required libraries.


Summary

Assemblies form the foundation of .NET applications by packaging compiled code into organized, deployable units. Executable assemblies start applications, while DLLs promote reuse by sharing functionality across systems.

In simple words:
  • Executable → starts the program
  • DLL → supports the program