Class Proxy<TIn, TOut>.Builder
- Namespace
- PatternKit.Structural.Proxy
- Assembly
- PatternKit.Core.dll
Fluent builder for Proxy<TIn, TOut>.
public sealed class Proxy<TIn, TOut>.Builder
- Inheritance
-
Proxy<TIn, TOut>.Builder
- Inherited Members
- Extension Methods
Remarks
The builder supports various proxy patterns:
- VirtualProxy(SubjectFactory) - Lazy initialization
- ProtectionProxy(AccessValidator) - Access control
- CachingProxy() - Result caching
- LoggingProxy(Action<string>) - Invocation logging
- Intercept(Interceptor) - Custom interception
- Before(Action<TIn>) / After(Action<TIn, TOut>) - Simple pre/post actions
Builders are mutable and not thread-safe. Each call to Build() creates an immutable proxy instance.
Methods
After(Action<TIn, TOut>)
Adds an action to execute after the subject returns.
public Proxy<TIn, TOut>.Builder After(Action<TIn, TOut> action)
Parameters
actionAction<TIn, TOut>Action to execute with input and output.
Returns
Examples
var proxy = Proxy<int, int>.Create(x => x * 2)
.After((input, result) => Console.WriteLine($"{input} -> {result}"))
.Build();
Remarks
Useful for side effects like logging results, notifications, or post-processing that doesn't modify the result.
Before(Action<TIn>)
Adds an action to execute before delegating to the subject.
public Proxy<TIn, TOut>.Builder Before(Action<TIn> action)
Parameters
actionAction<TIn>Action to execute with the input.
Returns
Examples
var proxy = Proxy<string, int>.Create(s => s.Length)
.Before(s => Console.WriteLine($"Processing: {s}"))
.Build();
Remarks
Useful for side effects like logging, validation, or notifications that don't affect the result.
Build()
Builds an immutable Proxy<TIn, TOut> with the configured behavior.
public Proxy<TIn, TOut> Build()
Returns
- Proxy<TIn, TOut>
A new Proxy<TIn, TOut> instance.
Exceptions
- InvalidOperationException
Thrown when the configuration is invalid.
CachingProxy()
Configures a caching proxy that memoizes results to avoid redundant subject invocations.
public Proxy<TIn, TOut>.Builder CachingProxy()
Returns
Examples
var proxy = Proxy<int, int>.Create(x => ExpensiveCalculation(x))
.CachingProxy()
.Build();
var r1 = proxy.Execute(5); // Calls subject
var r2 = proxy.Execute(5); // Returns cached result
Remarks
Caching Proxy Pattern: Stores results in a dictionary keyed by input. Subsequent calls with the same input return the cached result without invoking the subject.
Note: This requires to have proper equality semantics. For reference types, consider implementing IEquatable<T> or providing a custom comparer.
CachingProxy(IEqualityComparer<TIn>)
Configures a caching proxy with a custom equality comparer.
public Proxy<TIn, TOut>.Builder CachingProxy(IEqualityComparer<TIn> comparer)
Parameters
comparerIEqualityComparer<TIn>The equality comparer for cache keys.
Returns
Examples
var proxy = Proxy<string, int>.Create(s => s.Length)
.CachingProxy(StringComparer.OrdinalIgnoreCase)
.Build();
Intercept(Interceptor)
Adds a custom interceptor that has full control over subject invocation.
public Proxy<TIn, TOut>.Builder Intercept(Proxy<TIn, TOut>.Interceptor interceptor)
Parameters
interceptorProxy<TIn, TOut>.InterceptorThe interceptor delegate.
Returns
Examples
var proxy = Proxy<int, int>.Create(x => x * 2)
.Intercept((in int x, next) => {
if (x < 0) return 0; // Short-circuit negative inputs
return next(in x);
})
.Build();
Remarks
The interceptor receives the input and a delegate to the subject (or next layer). It can:
- Modify the input before calling the subject
- Skip calling the subject entirely (short-circuit)
- Modify the output before returning
- Add cross-cutting concerns (logging, timing, error handling)
LoggingProxy(Action<string>)
Configures a logging proxy that logs method invocations and results.
public Proxy<TIn, TOut>.Builder LoggingProxy(Action<string> logger)
Parameters
Returns
Examples
var proxy = Proxy<int, int>.Create(x => x * 2)
.LoggingProxy(Console.WriteLine)
.Build();
Remarks
Logging Proxy Pattern: Intercepts calls to log input and output for debugging or auditing. The logger is invoked before and after the subject execution.
ProtectionProxy(AccessValidator)
Configures a protection proxy that validates access before delegating to the subject.
public Proxy<TIn, TOut>.Builder ProtectionProxy(Proxy<TIn, TOut>.AccessValidator validator)
Parameters
validatorProxy<TIn, TOut>.AccessValidatorFunction that returns true if access is allowed.
Returns
Examples
var proxy = Proxy<User, bool>.Create(user => DeleteUser(user))
.ProtectionProxy(user => user.IsAdmin)
.Build();
Remarks
Protection Proxy Pattern: Controls access to the subject based on validation logic. If the validator returns false, an UnauthorizedAccessException is thrown.
VirtualProxy(SubjectFactory)
Configures a virtual proxy that lazily initializes the subject on first access.
public Proxy<TIn, TOut>.Builder VirtualProxy(Proxy<TIn, TOut>.SubjectFactory factory)
Parameters
factoryProxy<TIn, TOut>.SubjectFactoryFactory function that creates the real subject.
Returns
Examples
var proxy = Proxy<string, Database>.Create()
.VirtualProxy(() => new Database("connection-string"))
.Build();
// Database is not created until first Execute call
Remarks
Virtual Proxy Pattern: Delays expensive object creation until the object is actually needed. The factory is invoked only once, on the first call to Execute(in TIn), and the result is cached. Thread-safe initialization is guaranteed.