Table of Contents

Class Proxy<TIn, TOut>

Namespace
PatternKit.Structural.Proxy
Assembly
PatternKit.Core.dll

Fluent, allocation-light proxy that controls access to a subject and intercepts method invocations. Build once, then call Execute(in TIn) to invoke the subject through the proxy pipeline.

public sealed class Proxy<TIn, TOut> where TIn : notnull

Type Parameters

TIn

Input type passed to the subject.

TOut

Output type produced by the subject.

Inheritance
Proxy<TIn, TOut>
Inherited Members
Extension Methods

Examples

// Virtual Proxy - Lazy initialization
var proxy = Proxy<string, string>.Create()
    .VirtualProxy(() => ExpensiveResourceLoader())
    .Build();

var result = proxy.Execute("request"); // Initializes on first call

// Protection Proxy - Access control
var proxy = Proxy<User, bool>.Create(user => DeleteUser(user))
    .Intercept((user, next) => {
        if (!user.IsAdmin) return false;
        return next(user);
    })
    .Build();

Remarks

Mental model: A proxy acts as a surrogate or placeholder for another object (the subject). The proxy controls access to the subject and can add behavior before, after, or instead of delegating to it.

Use cases:

  • Virtual Proxy: Lazy initialization - defer creating expensive objects until needed.
  • Protection Proxy: Access control - validate permissions before allowing access.
  • Remote Proxy: Local representative for remote object - handle network calls.
  • Caching Proxy: Cache results to avoid redundant expensive operations.
  • Logging Proxy: Track method invocations for debugging or auditing.
  • Smart Reference: Reference counting, synchronization, or additional bookkeeping.
  • Mock/Test Double: Substitute real objects with test-friendly implementations.

Difference from Decorator: While both wrap objects, Decorator enhances functionality while maintaining the same interface contract. Proxy controls access to the subject and may provide a completely different implementation or skip delegation entirely.

Immutability: After Build(), the proxy is immutable and safe for concurrent reuse.

Methods

Create(Subject?)

Creates a new Proxy<TIn, TOut>.Builder for constructing a proxy.

public static Proxy<TIn, TOut>.Builder Create(Proxy<TIn, TOut>.Subject? subject = null)

Parameters

subject Proxy<TIn, TOut>.Subject

The real subject to proxy (optional if using virtual proxy).

Returns

Proxy<TIn, TOut>.Builder

A new Proxy<TIn, TOut>.Builder instance.

Examples

var proxy = Proxy<int, int>.Create(static x => x * 2)
    .Before(x => Console.WriteLine($"Input: {x}"))
    .Build();

Execute(in TIn)

Executes the proxy, potentially intercepting or controlling access to the real subject.

public TOut Execute(in TIn input)

Parameters

input TIn

The input value (readonly via in).

Returns

TOut

The result after applying proxy logic.

Remarks

Depending on the proxy configuration:

  • Direct proxies simply delegate to the subject.
  • Virtual proxies initialize the subject on first access.
  • Protection proxies validate access before delegating.
  • Interceptors can modify behavior at any point.