Click here to Skip to main content
15,116,653 members
Articles / Programming Languages / C#
Posted 6 Dec 2008


82 bookmarked

A tool for making C# decorators/proxies

Rate me:
Please Sign up or sign in to vote.
4.94/5 (27 votes)
6 Dec 2008CPOL4 min read
Describes a small VS add-in for making decorators from existing code.


This article discusses proxies/decorators in the context of the C# programming language, and shows a Visual Studio add-in which helps with the creation of such objects from your code.

To use the compiled add-in presented in this article, unzip the installation files into your Add-ins folder.

The Problem

If you’ve ever done textual code generation from C#, you probably know how convenient it is to subclass StringBuilder and add features specific for the type of code you want to build. You would also know that you really can’t subclass StringBuilder since it’s sealed. One option is to use extension methods, but what if you want to keep, say, the indentation level of a particular builder class? You end up making HashTables of WeakReference classes, and it all gets messy. Luckily, there is an (arguably) better way.

What I’m talking about is using a decorator instead. A decorator over the StringBuilder class can have all the methods that StringBuilder has, and more. Unlike the static extension method class, it can keep instance-specific state. It can also do other interesting and useful things, such as add proxy code, change return types, and other fun things.

Propagating (or proxying) lots of property assignments and method calls is no fun. That’s why I decided to write a small tool to do it for me. Let’s take a look at the tool in action.


Okay, so I want to make a general-purpose CodeBuilder class from which I’d like to derive CSharpBuilder, FSharpBuilder, NemerleBuilder, and so on. How do I do it?

Step I (optional): I open mscorlib in Reflector, locate the StringBuilder class, and copy it verbatim into my project file (any filename will do – it doesn’t really matter). If I was making a decorator over one of the files in my solution, I’d skip this step. Since StringBuilder is not around, I copy it.

Don’t bother fixing missing references or compiling the stuff – there’s no point. We just dragged in the source code so the decorator builder can find it.

Step II: Now, I right-click the project I want the decorator in and choose Add | Decorator:


Step III: Now, I select the StringBuilder class in the tree and tick its box. I type in the decorator name and press the OK button:


Since many StringBuilder methods return a StringBuilder object, I get a warning that a fluent interface has been detected:


Since I want to return CodeBuilder objects instead, I press Yes to make the substitution.

Step IV: This is the final step. I’ve got my class, so all I need to do now is add the missing references and do some clean-up so that all the wrongly translated parts are either removed or are made compilable (Reflector isn’t perfect, you know). Of course, I also remove the stuff I copied from Reflector – it’s no longer necessary. That’s it! I’ve got my decorator.

public class CodeBuilder
  private readonly StringBuilder stringBuilder;
  private CodeBuilder(StringBuilder stringBuilder)
    this.stringBuilder = stringBuilder;
  public int Capacity
      return stringBuilder.Capacity;
      stringBuilder.Capacity = value;

  // other members omitted

How Is It Done?

The add-in parses the project content tree and locates every .cs file. Then, it uses a free C# parser that I found on CodePlex to parse the files and build a visual tree out of them. The last part is really obvious – it just goes through the structure of the classes the user chose, and makes propagating methods/properties.

This project is my first (and only) use of WF. The decorator is built with a very simple workflow. In case you’re interested, here it is (not too exciting, is it?):


Future and Conclusion

You don’t have to make a decorator over just one class. If you are after some simulated multiple inheritance, you can specify two or more classes to decorate over. It will be up to you to extract interfaces and deal with name collisions, since my add-in doesn’t handle those directly.

This add-in is part of a set called P/factor that I wrote mainly for internal use. I will write about other code generation add-ins in the near future. Meanwhile, feel free to experiment with the add-in. I also appreciate comments and votes, since it's the only indicator I have of whether my articles are useful. Thanks!


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Dmitri Nеstеruk
Founder ActiveMesa
United Kingdom United Kingdom
I work primarily with the .NET technology stack, and specialize in accelerated code production via code generation (static or dynamic), aspect-oriented programming, MDA, domain-specific languages and anything else that gets products out the door faster. My languages of choice are C# and C++, though I'm open to suggestions.

Comments and Discussions

GeneralMy vote of 5 Pin
Kanasz Robert5-Nov-12 3:44
professionalKanasz Robert5-Nov-12 3:44 
GeneralAwesome, but... [modified] Pin
Ted Paulakis7-Apr-09 16:19
MemberTed Paulakis7-Apr-09 16:19 
GeneralRe: Awesome, but... Pin
Dmitri Nеstеruk25-Jun-09 1:25
MemberDmitri Nеstеruk25-Jun-09 1:25 
GeneralBTW.. Can also be done with ReSharper Pin
sefstrat9-Dec-08 20:21
Membersefstrat9-Dec-08 20:21 
GeneralRe: BTW.. Can also be done with ReSharper Pin
Dmitri Nеstеruk9-Dec-08 23:36
MemberDmitri Nеstеruk9-Dec-08 23:36 
GeneralGood Stuff Pin
seeblunt9-Dec-08 13:46
Memberseeblunt9-Dec-08 13:46 
The decorator pattern can be used to make it possible to extend (decorate) the functionality of a class at runtime. This works by adding a new decorator class that wraps the original class.
Now you may understand that the RtfBuilder is not a decorator (Followup of your comment on the RtfBuilder project).
RtfBuilder does not have all the methods of StringBuilder, just enough to get the job done.
AnswerRe: Good Stuff Pin
Dmitri Nеstеruk9-Dec-08 13:57
MemberDmitri Nеstеruk9-Dec-08 13:57 
GeneralOutstanding! Pin
Mike Doyon9-Dec-08 13:17
MemberMike Doyon9-Dec-08 13:17 
GeneralRe: Outstanding! Pin
Dmitri Nеstеruk9-Dec-08 13:49
MemberDmitri Nеstеruk9-Dec-08 13:49 
GeneralGreat job! Pin
NewSilence8-Dec-08 2:51
MemberNewSilence8-Dec-08 2:51 
GeneralYES! This is extremely useful Pin
sameeraperera7-Dec-08 6:42
Membersameeraperera7-Dec-08 6:42 
GeneralRe: YES! This is extremely useful Pin
Dmitri Nеstеruk7-Dec-08 6:47
MemberDmitri Nеstеruk7-Dec-08 6:47 
GeneralNice Work, One Thought Pin
Kavan Shaban6-Dec-08 23:51
MemberKavan Shaban6-Dec-08 23:51 
GeneralRe: Nice Work, One Thought Pin
Dmitri Nеstеruk7-Dec-08 0:20
MemberDmitri Nеstеruk7-Dec-08 0:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.