Introduction
The Java community has had the joy of dynamic proxies since JDK 1.3 and .NET has had its counterpart, the TransparentProxy
, since .NET version 1.0. However, the .NET TransparentProxy
isn't as easy to use as its Java counterpart. This is why DynamicProxy.NET was made.
What's a proxy?
Before we continue to look at DynamicProxy.NET it might be a good idea to recapture what a proxy is and what it can be used for. If you're familiar with proxies, just skip down to the next section.
The proxy design pattern was first made popular and well documented in the Gang Of Four (a.k.a. GoF) book: Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma (Eclipse), Richard Helm, Ralph Johnson and John Vlissides (a.k.a. the Gang of Four). The intent of the proxy pattern is to "Provide a surrogate or placeholder for another object to control access to it". An example of this is to control the security for the object (protection proxy), defer its instantiation until required (virtual proxy) and access to a remote object (remote proxy). There are other types of proxies such as a caching proxy, only your imagination sets the limit. The beauty of it is that the core of the pattern is the same.
The "bad" thing about proxies is that you have to make a replica class for the class you wish to proxy. This means, that if you wish to make a proxy for an Image
, say you wish to make a virtual proxy so the content of the image first is loaded when it's supposed to be rendered, you would have to create a new ImageProxy
class by hand, which has the same methods as the Image
class. This is where DynamicProxy.NET comes to the rescue; instead of creating the proxy by hand, the DynamicProxy.NET will automatically, at runtime, create a dynamic/transparent proxy for the object you wish to proxy. Sounds like magic? Well it isn't, it's just part of the beauty of platforms such as Java and .NET (and other dynamic languages for that matter).
Creating a proxy without DynamicProxy.NET
In the tutorial project, DynamicProxyTutorial, we've made a simple FileViewer
class which we want to create protection proxy for. Before we start coding we need to be aware of a special requirement that DynamicProxy.NET has:
Requirement: DynamicProxy.NET requires your code to use interface based implementation.
What this means is that you separate interface and implementation, so you for instance have an interface called ISimpleInterface
which defines the methods. You then create a class, for instance called SimpleClass
, which implements the interface ISimpleInterface
. .NET supports implementing more than one interface and DynamicProxy.NET also supports proxying of more than one interface.
This is the reason why the FileViewer
class implements the IFileViewer
interface. A class as simple as this, could normally do without an interface.
IFileViewer.cs - the interface for the file viewer:
using System;
namespace DynamicProxyTutorial
{
public interface IFileViewer
{
void ReadFromFile();
string Content {
get;
}
string FilePath {
get;
}
}
}
FileViewer.cs - the file viewer implementation:
using System;
using System.IO;
namespace DynamicProxyTutorial
{
public class FileViewer : IFileViewer {
private String content;
private String filePath;
public FileViewer(string filePath) {
this.filePath = filePath;
}
public void ReadFromFile() {
using (StreamReader reader = File.OpenText(filePath)) {
content = reader.ReadToEnd();
}
}
public string Content {
get {
return content;
}
}
public string FilePath {
get {
return filePath;
}
}
}
}
The point of this simple example is to protect the ReadFromFile()
method, which accesses a file on the hard drive. To protect that file from being read in the proxy, we "invent" our own protection system, where the user/programmer can specify which user ID is required to be allowed to access the file. This user ID, called the allowedUserID
in the code, is compared to the user ID, or rather the Name
of the current WindowsIdentity
, before allowing file access. This is not how it should be done in real life, but it serves as a simple working example.
Since we're going to implement the first proxy by hand, we have to create a new class, here called FileViewerProxy
, that must implement the IFileViewer
interface. The constructor takes the path to the file being viewed as well as the user ID of the user that should be allowed to view the file.
FileViewerProxy.cs - the hand made proxy:
using System;
using System.IO;
using System.Security.Principal;
namespace DynamicProxyTutorial {
public class FileViewerProxy : IFileViewer {
private string allowedUserID;
private IFileViewer realFileViewer;
public FileViewerProxy(string filePath, string allowedUserID) {
this.allowedUserID = allowedUserID;
realFileViewer = new FileViewer(filePath);
}
private void checkPermission() {
if (WindowsIdentity.GetCurrent().Name != allowedUserID) {
throw new SecurityException("From : " +
this.GetType().Name + "\r\nUserID '" +
WindowsIdentity.GetCurrent().Name +
" isn't allowed to read/write from the file: '" +
realFileViewer.FilePath + "'. " +
"Allowed user: '" + allowedUserID + "'");
}
}
public void ReadFromFile() {
checkPermission();
realFileViewer.ReadFromFile();
}
public string Content {
get {
return realFileViewer.Content;
}
}
public string FilePath {
get {
return realFileViewer.FilePath;
}
}
}
}
As you can see, we have to implement our own delegating version of all the methods in the IFileViewer
interface. In this case it isn't that bad, but consider a medium sized class, with 20 methods and 5 properties. It takes some time to create this by hand, plus you have to keep it in sync with changes to the interface. In the example, only the ReadFromFile()
method is checked for security constraints, since it's where all the interesting file handling happens. In the proxying ReadFromFile()
method, we call checkPermissions
before calling the real FileViewer
instance. If the permissions aren't satisfied, the checkPermissions
method will throw a SecurityException
, which will be propagated all the way to the main application.
Creating a proxy with DynamicProxy.NET
Instead of creating the proxied object methods and properties by hand, you can instead use DynamicProxy.NET. In this example we have some additional data, namely the allowedUserID
, that we need to keep for each proxy instance, so we decided to encapsulate it in a class of its own. The implementation can be found in the class DynamicFileViewerProxy
.
DynamicFileViewerProxy.cs - the DynamicProxy.NET implementation:
using System;
using System.Reflection;
using System.Security.Principal;
using Cramon.NetExtension.DynamicProxy;
namespace DynamicProxyTutorial {
public class DynamicFileViewerProxy {
private IDynamicProxy dynamicFileViewerProxy;
private string allowedUserID;
public DynamicFileViewerProxy(string filePath,
string allowedUserID) {
this.allowedUserID = allowedUserID;
IFileViewer realViewer = new FileViewer(filePath);
dynamicFileViewerProxy =
(IDynamicProxy)
DynamicProxyFactory.Instance.CreateProxy
(realViewer,
new InvocationDelegate(invocationHandler));
}
public IFileViewer Proxy {
get {
return (IFileViewer)dynamicFileViewerProxy;
}
}
private void checkPermission() {
if (WindowsIdentity.GetCurrent().Name != allowedUserID) {
IFileViewer realFileViewer =
(IFileViewer)dynamicFileViewerProxy.ProxyTarget;
throw new SecurityException("From : " +
this.GetType().Name + "\r\nUserID '"
+ WindowsIdentity.GetCurrent().Name +
" isn't allowed to read/write from the file: '" +
realFileViewer.FilePath + "'. " +
"Allowed user: '" + allowedUserID + "'");
}
}
private object invocationHandler(object target,
MethodBase method, object[] parameters) {
IFileViewer realViewer = (IFileViewer)target;
if (method.Name == "ReadFromFile") {
checkPermission();
}
return method.Invoke(realViewer, parameters);
}
}
}
A part from the checkPermission()
method and the constructor where we create a FileViewer
instance to proxy, all the implementation is kept in the invocationHandler()
method. The ReadFromFile()
and the two properties have been cut down to just 3 lines (if you remove the comments and unnecessary cast). The line:
dynamicFileViewerProxy
= (IDynamicProxy)DynamicProxyFactory.Instance.CreateProxy(realViewer,
new InvocationDelegate(invocationHandler));
is where the the dynamic proxy is created. It uses the CreateProxy(
) method in the DynamicProxyFactory
to create the dynamic proxy instance. The tricky part is that you need to tell the dynamic proxy what it should do when you call a method in it. For this we have the InvocationDelegate
. In the code above, we create a new InvocationDelegate
to the method invocationHandler
. The invocationHandler
is our implementation of the InvocationDelegate
. Every time a method is called on the dynamic proxy instance, the invocationHandler()
method is called. The invocationHandler()
is the controller, which is actively controlling the method invocation. The InvocationHandler
receives three parameters for each invocation:
target
: which is a reference to the real object being proxied. In this example, the target will refer to the FileViewer
instance.
method
: the method instance for the method that was called. The Method
class comes from the reflection API.
parameters
: an array containing all the parameters that was given to the method
.
When you're done doing what ever it is that your proxy is supposed to do, in our case check security, we call the real method on the target object, in the case the FileViewer
instance. This is again done using the reflection API again using this line of code: return method.Invoke(realViewer, parameters);
.
If you wish to get more information and details on the DynamicProxy.NET API, please refer to the online documentation.
The tutorial application
To make the tutorial more accessible, we've built a Windows application from where you can control the parameters of the application.

The checkbox "Use DynamicProxy.NET" decides whether the handmade FileViewerProxy
or the DynamicProxy.NET proxy, DynamicFileViewerProxy
class, is used. The "UserID allowed to view files" textbox specifies the user ID that is allowed to view the various files. It defaults to the value of the currently logged on user. Press the "Get Current User" to retrieve its information again. Press the "Select a File" button to select which file to view. We'll cover the "Compare Proxy Performance" in the performance section.
When a file has been selected, it is shown in the "large" textbox on the right hand side of the window. The code for creating the right proxy type is encapsulated in the FileViewerProxyFactory
. This was done to keep the code out of the MainForm
class.
FileViewerProxyFactory.cs - the factory for creating new proxy instances:
using System;
namespace DynamicProxyTutorial {
public class FileViewerProxyFactory {
private FileViewerProxyFactory() {
}
public static IFileViewer createProxy(string filePath,
string allowedUserID, bool useDynamicProxyNET) {
if (useDynamicProxyNET) {
return new DynamicFileViewerProxy(filePath,
allowedUserID).Proxy;
} else {
return new FileViewerProxy(filePath, allowedUserID);
}
}
}
}
The FileViewerProxyFactory
is being called from the selectFileButton_Click()
method.
selectFileButton_Click - the main method in the MainForm tutorial application:
private void selectFileButton_Click(object sender, System.EventArgs e) {
DialogResult dialogResult = selectFileDialog.ShowDialog();
if (dialogResult == DialogResult.OK) {
fileContentTextBox.Text = "";
IFileViewer fileViewer =
FileViewerProxyFactory.createProxy
(selectFileDialog.FileName,
allowedUserID.Text,
useDynamicProxyCheckBox.Checked);
try {
fileViewer.ReadFromFile();
} catch (SecurityException exception) {
MessageBox.Show(this, exception.Message,
"Security Exception", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
fileContentTextBox.Text = fileViewer.Content;
}
}
If the fileViewer.ReadFromFile()
method succeeds, the fileContentTextBox
is updated with the contents of the file (we recommend only opening text files ;-) ). If a security constraint isn't met and a SecurityException
is thrown a message box will explain what went wrong:

DynamicProxy.NET performance
How expensive is DynamicProxy.NET?
There's no doubt that proxying as a whole requires more memory and CPU time than no proxying at all, but with the speed of our processor and the amount of memory our computers have, this is not a big deal. What's more interesting is how much slower, CPU wise, is the DynamicProxy.NET approach compared to the hand made proxy? To give you a clue to how the two compare, we did a simple and non-scientific performance measurement. This performance test can be performed by clicking the "Compare Proxy Performance" button.
The result from my machine, a Intel Centrino 1.3 GHz, 512 MB RAM portable, is shown below:
Performance Test is running...
==================================================================
Tests per category : 1000000
GC wait per category: 5000 ms.
------------------------------------------------------------------
Average time to create Hand made proxy: 0,00036 ms.
Average time to create Dynamic proxy: 0,003054 ms.
Average time to call Content property Hand made proxy: 5E-05 ms.
Average time to call Content property Dynamic Proxy: 0,01444 ms.
==================================================================
Performance Test is done...
As you can see, the creation time for a dynamic proxy compared to a hand made one is about 10 times more expensive, but still only takes 0.003 milliseconds. The most expensive part of the DynamicProxy.NET approach is the method/property invocation part. It takes in average 0.015 milliseconds to invoke a method on a dynamic proxy, whereas it takes so little time, that it's almost beyond the scope of millisecond resolution timers, to invoke a method in the handmade proxy using direct method invocation. This difference is mainly due to the fact that reflection is used in DynamicProxy.NET and that reflective programming always will be slower than direct method invocation.
Conclusion
Proxy is a really good design pattern for many uses and DynamicProxy.NET makes it easy to create proxies dynamically at runtime, while still giving you good performance. This tutorial is by no means a complete guide to proxies nor to the features of the Transparent/Real proxy support, which DynamicProxy.NET relies upon, in .NET. We hope you've seen the idea and will start using proxies in your own applications where they make sense. Unless you have a really high performance system running many invocations, we would advocate using the DynamicProxy.NET approach compared to doing the proxies by hand. It saves you a lot of time and it's easy to work with. Should you, when profiling your application, find a performance problem caused by DynamicProxy.NET, you can always change that particular proxy with a handmade one and get better performance, while maintaining the advantages you can gain with proxies.