NProxy is a library for the .NET framework to create lightweight dynamic proxies.
There are already a few libraries out there which deal with dynamic proxy generation so why another dynamic proxy library? The answers which lead to the goals of the NProxy project can be summarized as follows:
- Provide an API to generate dynamic proxies based upon unsealed classes, abstract classes, interfaces and delegates in a unified way.
- General focus on quality attributes like performance, extensibility and lightweightness.
- Treat generic methods not as aliens and massively improve their invocation performance.
- Support the invocation of intercepted base methods.
- Make a library available which can be used as a base for AOP frameworks, mocking libraries, ...
- Dynamic proxy creation must be thread-safe.
Dynamic proxies provide an alternate, dynamic mechanism for implementing many common design patterns, including the Facade, Bridge, Interceptor, Decorator, Proxy, and Adapter patterns. While all of these patterns can be easily implemented using ordinary classes instead of dynamic proxies, in many cases the dynamic proxy approach is more convenient and compact and can eliminate a lot of handwritten or generated classes.
At the heart of the dynamic proxy mechanism is the IInvocationHandler
interface, shown below.
public interface IInvocationHandler
{
object Invoke(object target, MethodInfo methodInfo, object[] parameters);
}
The job of an invocation handler is to actually perform the requested method invocation on behalf of a dynamic
proxy. The invocation handler is passed a target object, a MethodInfo
object (from the System.Reflection
namespace)
and an array of parameters; in the simplest case, it could simply call the method MethodInfo.Invoke()
and return the
result. MethodInfo.Invoke()
directly invokes the target method without utilizing reflection.
Every proxy has an associated invocation handler that is called whenever one of the proxy's methods is called. Proxies can be created from unsealed classes, abstract classes, interfaces and delegates, and can implement an arbitrary number of interfaces. All interfaces are implemented explicitly to avoid member name conflicts.
To exclude events, properties and methods from beeing intercepted just apply the NonInterceptedAttribute
on the
member which should not be intercepted. This attribute has no effect when applied to abstract members.
To create dynamic proxies of only internally visible types, just add the following assembly attribute to your project.
[assembly: InternalsVisibleTo("NProxy.Dynamic")]
Interceptors provide the functionality of capturing calls to a target object at invocation time. The interception mechanism is part of the NProxy library and can be depicted as follows.
At the heart of the interception mechanism is the IInterceptor
and IInvocationContext
interface,
shown below.
public interface IInterceptor
{
object Intercept(IInvocationContext invocationContext);
}
The IInvocationContext
interface provides essential context information about the current invocation.
public interface IInvocationContext
{
object Target { get; }
MethodInfo Method { get; }
object[] Parameters { get; }
object Proceed();
}
The easiest way to add interceptors in an aspect oriented manner is to apply attributes on classes, interfaces, events, properties or methods which
implement the IInterceptionBehavior
interface.
public interface IInterceptionBehavior
{
void Apply(MemberInfo memberInfo, ICollection<IInterceptor> interceptors);
void Validate(MemberInfo memberInfo);
}
To get the latest version of NProxy just add it to your project using NuGet.
PM> Install-Package NProxy.Core
Detailed release notes can be found here.
See here for details.
See here for details.
Copyright © Martin Tamme. See LICENSE for details.