Mediator Pattern in C#: Definition, Examples, Pros, Cons, and Use Cases

Mediator Pattern in C#: Definition, Examples, Pros, Cons, and Use Cases

The Mediator pattern in C# is a behavioral design pattern that centralizes communication between objects by introducing a mediator object that coordinates their interactions.

The Mediator pattern reduces direct dependencies between objects by making them communicate through a mediator instead of referencing each other directly. This helps create loosely coupled systems where object interactions are centralized and easier to manage. Each participating object, called a colleague, sends requests to the mediator, and the mediator coordinates communication between colleagues. The mediator encapsulates interaction logic, reducing complex object relationships and improving maintainability. In C#, the Mediator pattern is commonly used in UI frameworks, messaging systems, chat applications, CQRS architectures, and workflow coordination systems.

Why We Use Mediator Pattern in C#?

We use the Mediator pattern in C# to:

• Reduce tight coupling between objects
• Centralize communication logic
• Simplify object collaboration
• Improve maintainability
• Prevent complex object dependency graphs
• Support cleaner architecture
• Simplify component reuse
• Manage communication workflows efficiently

When Should We Use Mediator Pattern in C#?

The Mediator pattern should be used when:

• Many objects communicate with each other
• Object dependencies become difficult to manage
• Communication logic is complex
• Components should remain loosely coupled
• Reusable independent components are needed
• Centralized coordination is preferred
• UI components interact heavily

Common Programming Problems Solved by Mediator Pattern

• UI component communication
• Chat room systems
• Workflow coordination
• Event orchestration
• CQRS request handling
• Air traffic control systems
• Smart home coordination
• Messaging systems
• Notification hubs

Structure of Mediator Pattern in C#

Typical participants:

• Mediator Interface
• Concrete Mediator
• Colleague Classes
• Client

Basic workflow:

• Colleague sends message to mediator
• Mediator receives request
• Mediator decides target recipients
• Mediator coordinates communication

Mediator Pattern Examples in C#

Example 1: Chat Room System

Users in a chat room should communicate without directly referencing each other.

using System;
using System.Collections.Generic;

public interface IChatMediator
{
    void SendMessage(string message, User user);
    void AddUser(User user);
}

public class ChatMediator : IChatMediator
{
    private List<User> users = new List<User>();

    public void AddUser(User user)
    {
        users.Add(user);
    }

    public void SendMessage(string message, User sender)
    {
        foreach (var user in users)
        {
            if (user != sender)
            {
                user.Receive(message);
            }
        }
    }
}

public class User
{
    private IChatMediator mediator;

    public string Name { get; }

    public User(IChatMediator mediator, string name)
    {
        this.mediator = mediator;
        Name = name;
    }

    public void Send(string message)
    {
        Console.WriteLine($"{Name} sends: {message}");
        mediator.SendMessage(message, this);
    }

    public void Receive(string message)
    {
        Console.WriteLine($"{Name} receives: {message}");
    }
}

public class Program
{
    public static void Main()
    {
        IChatMediator mediator = new ChatMediator();

        User john = new User(mediator, "John");
        User alice = new User(mediator, "Alice");

        mediator.AddUser(john);
        mediator.AddUser(alice);

        john.Send("Hello Alice");
    }
}

Example 2: Air Traffic Control System

Aircraft should communicate through a control tower instead of directly with each other.

using System;

public interface IControlTower
{
    void SendMessage(string message, Aircraft aircraft);
}

public class ControlTower : IControlTower
{
    public void SendMessage(string message, Aircraft sender)
    {
        Console.WriteLine($"Tower relays from {sender.Name}: {message}");
    }
}

public class Aircraft
{
    private IControlTower tower;

    public string Name { get; }

    public Aircraft(IControlTower tower, string name)
    {
        this.tower = tower;
        Name = name;
    }

    public void Send(string message)
    {
        tower.SendMessage(message, this);
    }
}

public class Program
{
    public static void Main()
    {
        IControlTower tower = new ControlTower();

        Aircraft plane1 = new Aircraft(tower, "Flight A1");
        Aircraft plane2 = new Aircraft(tower, "Flight B2");

        plane1.Send("Requesting landing permission");
        plane2.Send("Ready for takeoff");
    }
}

Example 3: Smart Home Coordination

Smart home devices should coordinate actions through a central hub.

using System;

public interface ISmartHomeMediator
{
    void Notify(string eventName, Device sender);
}

public class SmartHomeHub : ISmartHomeMediator
{
    public void Notify(string eventName, Device sender)
    {
        if (eventName == "MotionDetected")
        {
            Console.WriteLine("Hub turns on hallway lights");
        }
    }
}

public abstract class Device
{
    protected ISmartHomeMediator mediator;

    public Device(ISmartHomeMediator mediator)
    {
        this.mediator = mediator;
    }
}

public class MotionSensor : Device
{
    public MotionSensor(ISmartHomeMediator mediator) : base(mediator)
    {
    }

    public void DetectMotion()
    {
        Console.WriteLine("Motion detected");
        mediator.Notify("MotionDetected", this);
    }
}

public class Program
{
    public static void Main()
    {
        ISmartHomeMediator hub = new SmartHomeHub();

        MotionSensor sensor = new MotionSensor(hub);

        sensor.DetectMotion();
    }
}

Most Known Real-World Use Cases in C#

• ASP.NET CQRS mediator libraries
• Chat applications
• UI dialog coordination
• Workflow orchestration
• Event aggregation systems
• Air traffic control systems
• Smart home automation
• Multiplayer game communication
• Enterprise messaging systems

Advantages of Mediator Pattern in C#

• Reduces object coupling
• Simplifies communication logic
• Centralizes interaction management
• Improves maintainability
• Enhances component reusability
• Reduces dependency complexity
• Makes systems easier to extend
• Improves code readability

Disadvantages (Weak Points) of Mediator Pattern in C#

• Mediator can become overly complex
• Centralized logic may create bottlenecks
• Large mediators may violate Single Responsibility Principle
• Adds extra abstraction layer
• Debugging communication flow can become harder
• Too many colleagues may overload mediator
• Can evolve into a “god object”

Comparison with Similar Patterns

Pattern Main Purpose Communication Style Coupling Level Typical Usage Main Difference from Mediator
Mediator Centralize object communication Through mediator Loose UI systems, workflows Uses centralized coordination for communication
Observer Notify subscribers Broadcast events Loose Event systems Focuses on event subscription rather than coordination
Facade Simplify subsystem access One-way interface Moderate API wrappers Provides simplified access instead of coordinating peers
Command Encapsulate requests Invoker to receiver Loose Undo systems, queues Encapsulates operations rather than object interactions
Chain of Responsibility Pass requests through handlers Sequential chain Loose Middleware pipelines Processes requests sequentially instead of coordinating communication

Simplified UML-Style Structure

Component Responsibility
Mediator Interface Defines communication methods
ConcreteMediator Coordinates colleague interactions
Colleague Sends requests through mediator
ConcreteColleague Implements business functionality
Client Creates mediator and colleagues

Creational Patterns in C#

13. Chain of Responsibility
14. Iterator
15. Momento
16. State
17. Template Method
18. Command
19. Mediator
20. Observer
21. Strategy
22. Visitor