.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core, .NET 8/9/10
  • Azure - Azure Functions, App Services, Azure SQL, Service Bus, Blob Storage, Key Vault, API Management (APIM), Logic Apps and Application Insights
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF
ENCODING TEST: ───────────────► ↓ ↑ ← →

Association, Aggregation, and Composition in OOP (with C#)

"How are these classes related?" is one of the most common questions in object-oriented design, and the answer usually comes down to three relationship types: association, aggregation, and composition. They all describe one class referencing another, but the strength of the relationship, and what happens to one object when the other is destroyed, is different for each.

Association   - two classes are related, but neither owns the other.
Aggregation    - a "has-a" relationship where the child can exist independently ("owns a", weak).
Composition    - a "has-a" relationship where the child cannot exist without the parent (strong).

Association: Two Classes Simply Know About Each Other

Association is the most general relationship. One object uses or interacts with another, but there is no ownership in either direction. Both objects are created and destroyed independently.

public class Teacher
{
    public string Name { get; set; }
}

public class Student
{
    public string Name { get; set; }
    public Teacher Teacher { get; set; }
}

A Student is associated with a Teacher, but the two are not tied together. The same Teacher instance could be associated with many students, and if a Student object is discarded, the Teacher is completely unaffected.

var teacher = new Teacher { Name = "Mrs. Alvarez" };

var student1 = new Student { Name = "Sam", Teacher = teacher };
var student2 = new Student { Name = "Priya", Teacher = teacher };

Aggregation: "Has-A" With Independent Lifetimes

Aggregation is a special form of association that represents a whole/part relationship, where the "whole" holds a collection of "parts", but those parts can exist on their own and can even be shared between wholes.

public class Engineer
{
    public string Name { get; set; }
}

public class Team
{
    public string Name { get; set; }
    public List<Engineer> Engineers { get; set; } = new List<Engineer>();
}

An Engineer can be added to a Team, but the engineer is created independently, outside of the team, and passed in.

var alice = new Engineer { Name = "Alice" };
var bob = new Engineer { Name = "Bob" };

var team = new Team { Name = "Platform Team" };
team.Engineers.Add(alice);
team.Engineers.Add(bob);

If the Team object is discarded, alice and bob keep existing. They could just as easily be moved to a different team.

team = null; // Alice and Bob still exist, referenced elsewhere

Composition: "Has-A" With a Shared Lifetime

Composition is a stronger whole/part relationship. The part is created and owned by the whole, and it has no meaningful existence outside of it. When the owning object goes away, the parts go away with it.

public class Room
{
    public string Name { get; set; }
}

public class House
{
    public string Address { get; set; }
    private readonly List<Room> _rooms = new List<Room>();

    public House(string address)
    {
        Address = address;

        _rooms.Add(new Room { Name = "Kitchen" });
        _rooms.Add(new Room { Name = "Living Room" });
    }

    public IReadOnlyList<Room> Rooms => _rooms;
}

The Room objects are constructed inside the House constructor. There is no way to create a Room that belongs to this house from outside of it, and there is no way to move a Room to a different House.

var house = new House("221B Baker Street");

Console.WriteLine(house.Rooms[0].Name); // Kitchen

Once house is discarded, nothing else references its Room objects, so they become eligible for garbage collection along with it.

house = null; // Kitchen and Living Room become eligible for garbage collection too

Comparing the Three Side by Side

Association:
Student ───────────────► Teacher
        no ownership, independent lifetimes

Aggregation:
Team    ◇──────────────► Engineer
        whole/part, but part can outlive the whole

Composition:
House   ◆──────────────► Room
        whole/part, part cannot outlive the whole

In UML diagrams, aggregation is drawn with a hollow diamond on the "whole" side, and composition with a filled diamond, which is a useful way to remember the difference: hollow means the part can be hollowed out and used elsewhere, filled means it is permanently part of the whole.


Why the Distinction Matters

This is not just an academic exercise. The relationship type affects how you write constructors, how you manage object lifetimes, and how you think about disposal:

  1. Association: classes reference each other, but neither is responsible for creating or destroying the other.
  2. Aggregation: the container holds references to objects created elsewhere, so removing an item from the container should not destroy it.
  3. Composition: the owner is responsible for creating its parts, and often for disposing of them too, for example implementing IDisposable to clean up composed objects.
public class House : IDisposable
{
    private readonly List<Room> _rooms = new List<Room>();

    // ... constructor as before ...

    public void Dispose()
    {
        // Composition often implies the owner cleans up its parts.
        _rooms.Clear();
    }
}

Final Mental Model

  1. Association: "uses-a" - a loose relationship between independent objects.
  2. Aggregation: "has-a", weak ownership - the part can exist and be reused without the whole.
  3. Composition: "has-a", strong ownership - the part is created by the whole and dies with it.
Association   Student references a Teacher that exists independently.
Aggregation    Team holds Engineers that exist independently and could belong to another team.
Composition    House creates and owns Rooms that cannot exist without it.