Dynamic Proxies in .NET
Spring and Java
- The AOP functionality that is offered in spring here
what is offered in Spring.
Categorization of approaches
- 'RealProxy' Leverage the functionality provied by inheriting from the class ContextBoundObject
- 'CodeDom' Generate proxy source code at runtime using the Code Document Object Model, then compile it and load it.
- 'Reflection.Emit' Generate proxy IL code at runtime using the Reflection.Emit namespace.
Sebastien Bouchet, who works with the Spring.NET developer Sami Jaber at dotnetguru.org, writes a good article
on the different approaches to Dynamic Proxies. You can run it through babel fish
if you can't read French.
Books/Articles/Blogs
Other Projects
Pros and Cons
Well the ContextBoundObject approach is pretty much off the table, since it enforces itself on the object model. The proxies objects should not be coupled to the dynamic proxy implementation. - Mark
RealProxy:
- As you mentioned what I dislike the most with the ContextBoundObject approach is that it constrains my inheritance tree. If have total control on the components I write, I can work around this by forcing all my classes to inherit from a common base class which happens to subclass ContextBoundObject, but in case I have to write components that for some reason need to inherit from a third-party class, oops I'm in trouble
Reflection.Emit:
- is efficient ay first glance (as long as you maintain a proxy cache per proxified type, which I did not implement in the article's source code) because once the proxy is generated, method invocation does not involve any form of marshalling between parameters on the stack and a IMessage structure. The only real overhead comes from reflection as well as additional boxing/unboxing. Now this overhead could be easily quantified
- I agree that it is "heavy" given that using Reflection.Emit is SO technical and bug-prone ! But once abstracted out in a framework tested with tons of NUnit test cases, this should not be a problem.
- one issue could come from further revisions of the .NET framework and CLR backwards-incompatible with generated IL. I tested the article source code with Whidbey's PDC build and it was all fine, but it might well be an issue in the long term.
- forces you to have a factory method, the new() operator is irrelevant, whereas the ContextBound approach allows you to stick to "traditional" instanciation. No problem with IoC containers which enforce this approach anyway by requiring applications to ask the container for an instance of a component ("ctx.getBean")
Well i strongly agree with both your description about these issues, and personally i think that in the 1st case, the hierarchy problem can be easily solved (as you already mentioned by inheriting into your base class from ContextBound), the only problem that I see is in the case of ByValueObject's, i mean as you can see the ContextBoundObject actually inherits MarshalByRef, so especially in remotting scenarios...well u can see the problem.
On the other hand, comparring with the 2nd option, I would say that this raises a question: Which one of those is more "heavy"???
I would basically go for the 1st solution beign favorite, considering that in remote scenarios, one is already aware of the different options within the framework, and accepted the "heaviness" it adds.
On the 2nd option of course, AT ALL TIME , you have the "heaviness" so for critical apps. i would definitelly use 1st.
Cheers,
C. Marius