.NET Components

In .NET, a component is an assembly: a compiled, versioned unit (.dll) that exposes public types and hides the rest. Applications are built by wiring components together through interfaces, and the built-in dependency injection container decides which implementation each component receives.

Paradigm: Component-Oriented Programming

What Makes .NET Components Special

  • Assemblies as the unit of deployment. An assembly is versioned and shipped on its own, often as a NuGet package. Only public types are visible outside it.
  • Programming to interfaces. Components depend on IClock, not on SystemClock. Swapping implementations does not touch the consumer.
  • Dependency injection built in. Microsoft.Extensions.DependencyInjection creates components and supplies their dependencies with a chosen lifetime: singleton, scoped or transient.
  • Composition, not inheritance. Constructor parameters declare what a component needs, which makes it easy to test with fakes.
  • A long component history. COM, .NET Remoting, MEF and Windows Forms controls all explored components. Modern .NET converges on packages, DI and plugin loading.

Example: A greeter that depends on an interface

using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddSingleton<IClock, SystemClock>();
services.AddTransient<Greeter>();

using var provider = services.BuildServiceProvider();
var greeter = provider.GetRequiredService<Greeter>();
Console.WriteLine(greeter.Greet("Ada"));

public interface IClock
{
    DateTime Now { get; }
}

public class SystemClock : IClock
{
    public DateTime Now => DateTime.Now;
}

public class Greeter(IClock clock)
{
    public string Greet(string name) =>
        clock.Now.Hour < 12 ? $"Good morning, {name}" : $"Hello, {name}";
}

How It Works

  • IClock is the published contract. SystemClock is one implementation and could be replaced by a fixed clock in a test.
  • Greeter receives its IClock through a primary constructor (C# 12). It never creates or names a concrete clock.
  • The composition happens in one place: AddSingleton<IClock, SystemClock> registers the wiring, and the container resolves Greeter with its dependency filled in.
  • The top-level statements come first and the type declarations after them, which C# requires for a program with no Main method.

History and Where It Is Used

ASP.NET Core, worker services, MAUI and most modern .NET applications are assembled this way, using NuGet packages as deployable components. Plugin systems load assemblies at runtime with AssemblyLoadContext. See the C# roadmap for a complete course, and Demo 12 for a component example.

Learn More