.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
publictypes are visible outside it. - Programming to interfaces. Components depend on
IClock, not onSystemClock. Swapping implementations does not touch the consumer. - Dependency injection built in.
Microsoft.Extensions.DependencyInjectioncreates 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
IClockis the published contract.SystemClockis one implementation and could be replaced by a fixed clock in a test.Greeterreceives itsIClockthrough 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 resolvesGreeterwith its dependency filled in. - The top-level statements come first and the type declarations after them, which C# requires for a program with no
Mainmethod.
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.