Proxy Pattern in C#

The Proxy Pattern provides a stand-in or placeholder for another object. It acts as a gatekeeper — managing access to that object and adding extra behaviour like logging, validation, caching, or security checks without changing the original class.

This makes it useful when you want to add functionality around an object but keep the object itself untouched.

Real-Life Analogy: Proxy Server

Imagine you use a proxy server when browsing the internet. Instead of your browser sending requests directly to websites, it sends them to the proxy. The proxy then contacts the website, fetches the data, and returns it to you.

While doing that, it might filter some content, cache popular responses, or hide your IP address. You don't connect to the website directly — the proxy acts as an intermediary.

Proxy server sitting between browser and real website
Like a browser talking to a proxy server instead of a website, the Proxy Pattern adds a layer that can filter, log, or control access to the real object.

Benefits of Proxy Pattern

The Proxy Pattern helps you wrap additional logic around access to an object without modifying the object itself. It makes systems more flexible, testable, and maintainable by separating concerns.

Some of the key advantages include:

  • Encapsulates access control
  • Supports lazy-loading and remote access
  • Helps with logging, caching, and validation

When Should You Use It?

The Proxy Pattern is a good fit when you want to intervene or monitor interactions with a particular object, but don't want to touch its internal code. It's great for adding behaviour dynamically while maintaining separation of concerns.

  • Adding access control or authorisation logic
  • Delaying object creation until it's really needed (lazy-loading)
  • Logging or monitoring usage transparently
  • Caching outputs from heavy operations

When Not to Use It: Avoid this pattern if there's no added logic needed between the client and object, or if extra layers would make debugging more difficult.

What to Implement

The Proxy Pattern typically involves:

An interface that defines the operations, a real class that does the actual work, and a proxy class that implements the same interface but wraps the real object.

  • Subject Interface: The common contract used by both the proxy and the real object
  • Real Subject: The actual object containing the main logic
  • Proxy: Controls and delegates access to the real subject

How It Works in C#


// Subject Interface
public interface IWebsite
{
    void Access(string url);
}

// Real Subject
public class RealWebsite : IWebsite
{
    public void Access(string url)
    {
        Console.WriteLine($"Accessing real website: {url}");
    }
}

// Proxy
public class ProxyServer : IWebsite
{
    private RealWebsite realWebsite = new RealWebsite();

    public void Access(string url)
    {
        if (IsBlocked(url))
        {
            Console.WriteLine("Access Denied: This site is blocked.");
            return;
        }

        Console.WriteLine("Logging: " + url);
        realWebsite.Access(url);
    }

    private bool IsBlocked(string url)
    {
        return url.Contains("restricted");
    }
}

Usage:


IWebsite proxy = new ProxyServer();

proxy.Access("example.com");         // Allowed
proxy.Access("restricted-site.com"); // Blocked

Final Thoughts

Think of the Proxy Pattern as a buffer between your code and the actual object — like a web proxy that stands in front of real websites.

It's great when you want to filter access, log activity, or delay object creation — all without modifying the real class.