What are assemblies and namespaces in .NET?

8 minintermediate.NETassembliesnamespaces

Quick Answer

Assemblies are compiled units of deployment (.dll/.exe) containing IL code, metadata, and resources. They have unique identity and are the smallest deployment unit. Namespaces are logical groupings of related types to avoid naming conflicts and organize code hierarchically. One assembly can contain multiple namespaces, and multiple assemblies can share the same namespace.

Detailed Answer

Assemblies are the fundamental unit of deployment and versioning in .NET. They contain compiled code, metadata, and resources that make up a .NET application.

Namespaces are logical groupings of related types that help organize code and avoid naming conflicts.

Assemblies:

What is an Assembly:

  • A compiled unit of code (usually a .dll or .exe file)
  • Contains Intermediate Language (IL) code, metadata, and resources
  • The smallest unit of deployment in .NET
  • Has a unique identity (name, version, culture, public key)

Assembly Structure:

MyAssembly.dll
├── Assembly Manifest (metadata)
├── Type Metadata
├── IL Code
├── Resources (images, strings, etc.)
└── Security Information

Types of Assemblies:

// 1. Executable Assembly (.exe)
// Contains an entry point (Main method)
// Can be run directly

// 2. Library Assembly (.dll)
// Contains reusable code
// Cannot be run directly
// Referenced by other assemblies

// Example: Creating a library assembly
namespace MyLibrary
{
    public class Calculator
    {
        public int Add(int a, int b) => a + b;
        public int Multiply(int a, int b) => a * b;
    }
}

// Compile to: MyLibrary.dll

Assembly Manifest:

// Assembly information (in AssemblyInfo.cs or project file)
[assembly: AssemblyTitle("MyApplication")]
[assembly: AssemblyDescription("A sample application")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyCompany("MyCompany")]
[assembly: AssemblyProduct("MyProduct")]
[assembly: AssemblyCopyright("Copyright © 2024")]

Global Assembly Cache (GAC):

// GAC is a machine-wide cache for shared assemblies
// Only available in .NET Framework (not in .NET Core/5+)
// Used for system assemblies and shared libraries

// Installing to GAC (Framework only)
gacutil -i MyAssembly.dll

// Strong-named assemblies can be installed in GAC
[assembly: AssemblyKeyFile("MyKey.snk")]

Namespaces:

What is a Namespace:

  • A logical grouping of related types
  • Helps avoid naming conflicts
  • Provides a hierarchical organization
  • Similar to folders in a file system

Namespace Declaration:

// Single namespace
namespace MyCompany.MyProject
{
    public class User { }
    public class Product { }
}

// Multiple namespaces in same file
namespace MyCompany.MyProject.Data
{
    public class UserRepository { }
}

namespace MyCompany.MyProject.Services
{
    public class UserService { }
}

// Nested namespaces
namespace MyCompany
{
    namespace MyProject
    {
        namespace Data
        {
            public class UserRepository { }
        }
    }
}

Using Namespaces:

// Fully qualified name
MyCompany.MyProject.User user = new MyCompany.MyProject.User();

// Using directive
using MyCompany.MyProject;
User user = new User();

// Using alias
using Data = MyCompany.MyProject.Data;
Data.UserRepository repo = new Data.UserRepository();

// Global using (C# 10+)
global using System;
global using System.Collections.Generic;

Assembly vs Namespace Relationship:

// One assembly can contain multiple namespaces
// MyLibrary.dll contains:
namespace MyCompany.Data
{
    public class UserRepository { }
}

namespace MyCompany.Services
{
    public class UserService { }
}

// Multiple assemblies can contain the same namespace
// MyLibrary1.dll and MyLibrary2.dll both contain:
namespace MyCompany.Common
{
    // Different types in each assembly
}

Assembly Loading:

// Load assembly dynamically
Assembly assembly = Assembly.LoadFrom("MyLibrary.dll");
Type type = assembly.GetType("MyCompany.MyClass");
object instance = Activator.CreateInstance(type);

// Get all types in assembly
Assembly currentAssembly = Assembly.GetExecutingAssembly();
Type[] types = currentAssembly.GetTypes();

// Get assembly from type
Assembly userAssembly = typeof(User).Assembly;

Best Practices:

Assemblies:

  1. Keep assemblies focused - one responsibility per assembly
  2. Use strong naming for shared libraries
  3. Version your assemblies properly
  4. Minimize assembly dependencies to reduce complexity
  5. Use assembly attributes for metadata

Namespaces:

  1. Follow naming conventions - Company.Project.Feature
  2. Keep namespaces shallow - avoid deep nesting
  3. Use meaningful names that describe the purpose
  4. Group related types together
  5. Avoid namespace conflicts with well-known libraries

Example Project Structure:

MyProject/
├── MyProject.Core/           (Assembly)
│   ├── Models/              (Namespace)
│   │   ├── User.cs
│   │   └── Product.cs
│   └── Interfaces/          (Namespace)
│       └── IRepository.cs
├── MyProject.Data/          (Assembly)
│   └── Repositories/        (Namespace)
│       └── UserRepository.cs
└── MyProject.Web/           (Assembly)
    └── Controllers/         (Namespace)
        └── UserController.cs

Related Resources