Part 3: Adding a dynamic decorator to an object – the “Why not”

by Tobias Hertkorn on December 21st, 2009

Krzysztof pointed me to his post Castle Dynamic Proxy FAQ: why there’s no “class proxy with target” why the dynamic decorator is not part of Castles’s DynamicProxy implementation yet.

Looking at the code one realizes that the real problem is, that IsAdult() is not virtual. That’s why the decorator is not able to intercept and redirect that call to the target. There is no way around it – that is a real bug and it does show why a class proxy with a target is indeed dangerous. Thanks for pointing it out to me, Krzysztof!

The question we have to ask now is: If we refuse to generate the proxy, if any member more visible than protected is non-virtual, would that get rid of the bug? I would argue that it will, since the proxy will now be able to redirect the call to the target and everything works out fine. Or am I again missing something?

December 21st, 2009 6:44 pm | Comments (0)

Adding a dynamic decorator to an object

by Tobias Hertkorn on December 19th, 2009

I am really confused that non of the dynamic proxy frameworks out there allow me to add dynamic behavior after the fact - I have an instantiated object and need to add behavior when a property is accessed. Like this:

C#:
  1. var myType = new MyType();
  2. myType.Property = "Test";
  3.  
  4. var interceptor = new MyInterceptor();
  5. MyType wrappedMyType = proxyGenerator.GenerateProxy(myType, interceptor);
  6. wrappedMyType.Property = "Test2";
  7.  
  8. Debug.Assert(myType.Property == "Test2");
  9. Debug.Assert(interceptor.SetterWasCalled);

All current frameworks need me to instantiate the object using the proxy generator. Which is unfortunate, because, unlike in the example, I plan to introduce the decorator in a part of my application that is conceptionally in a completely different region of the application's source code. It would just not make sense to introduce the knowledge about the additional behavior at the point of object creation.

It should be fairly easy to pull off, since I am already able to do it by hand:

C#:
  1. public class MyInterceptor : IInterceptor<MyType>
  2. {
  3.     public void InterceptGetter(IProxy proxy, MyType @object, string propertyName, out object value)
  4.     {
  5.         // do something before get
  6.         proxy.ProceedGetter(propertyName, out value);
  7.         // do something after get
  8.     }
  9.  
  10.     public void InterceptSetter(IProxy proxy, MyType @object, string propertyName, object value)
  11.     {
  12.         // do something before set
  13.         proxy.ProceedSetter(propertyName, value);
  14.         // do something after set
  15.         m_setterCalled = true;
  16.     }
  17.  
  18.     private bool m_setterCalled = false;
  19.     public bool SetterWasCalled
  20.     {
  21.         get { return m_setterCalled; }
  22.     }
  23. }
  24.  
  25. public class MyType
  26. {
  27.     public virtual string Property { get; set; }
  28. }
  29.  
  30. /////// AUTOGENERATED PROXY ///////
  31.  
  32. public class MyTypeProxy : MyType, IProxy
  33. {
  34.     private MyType m_object;
  35.     private IInterceptor<MyType> m_interceptor;
  36.  
  37.     public MyTypeProxy(MyType @object, IInterceptor<MyType> interceptor)
  38.     {
  39.         m_object = @object;
  40.         m_interceptor = interceptor;
  41.     }
  42.  
  43.     public override string Property
  44.     {
  45.         get
  46.         {
  47.             object value;
  48.             m_interceptor.InterceptGetter(this, m_object, "Property", out value);
  49.             return (string)value;
  50.         }
  51.         set { m_interceptor.InterceptSetter(this, m_object, "Property", value); }
  52.     }
  53.  
  54.     public void ProceedGetter(string propertyName, out object value)
  55.     {
  56.         if (propertyName == "Property")
  57.         {
  58.             value = m_object.Property;
  59.         }
  60.         else
  61.         {
  62.             throw new MissingMemberException();
  63.         }
  64.     }
  65.  
  66.     public void ProceedSetter(string propertyName, object value)
  67.     {
  68.         if (propertyName == "Property")
  69.         {
  70.             m_object.Property = (string)value;
  71.         }
  72.         else
  73.         {
  74.             throw new MissingMemberException();
  75.         }
  76.     }
  77. }
  78.  
  79. /////// SUPPORTING CODE ///////
  80.  
  81. public interface IProxy
  82. {
  83.     void ProceedGetter(string propertyName, out object value);
  84.     void ProceedSetter(string propertyName, object value);
  85. }
  86.  
  87. public interface IInterceptor<T>
  88. {
  89.     void InterceptGetter(IProxy proxy, T @object, string propertyName, out object value);
  90.     void InterceptSetter(IProxy proxy, T @object, string propertyName, object value);
  91. }
  92.  
  93. /////// TEST ///////
  94.  
  95. public static class Test
  96. {
  97.     public static void ProxyTest()
  98.     {
  99.         var myType = new MyType();
  100.         myType.Property = "Test";
  101.  
  102.         var interceptor = new MyInterceptor();
  103.         MyType wrappedMyType = GenerateProxy(myType, interceptor);
  104.         wrappedMyType.Property = "Test2";
  105.  
  106.         Debug.Assert(myType.Property == "Test2");
  107.         Debug.Assert(interceptor.SetterWasCalled);
  108.     }
  109.  
  110.     // This method belongs in a proxy generator
  111.     private static MyType GenerateProxy(MyType myType, IInterceptor<MyType> interceptor)
  112.     {
  113.         return new MyTypeProxy(myType, interceptor);
  114.     }
  115. }

Who will help me to adapt the API to the Castle DynamicProxy API and to write the actual proxy/decorator generation? :)

December 19th, 2009 6:01 pm | Comments (3)

Reading code

by Tobias Hertkorn on August 5th, 2008

Tonight I did not feel much like working ... so instead I finally, after a couple of weeks of abstinence, did dig into somebody else’s code again. For me still the ultimate way of learning and improving my coding skills.

Today's code repository come from Jeremy D. Miller and is part of his storyteller project. Actually I was not too much interested in the story teller project itself, even though it is definitively worth checking out. Instead I did take a closer look at all his framework code in the namespaces shadetree.*

I am not going to go into any details; you certainly should check it out yourself. It is definitively a shade tree... And I am not going to bitch about the fact that it did not compile out of the box and that Jeremy seems to camel case private methods and pascal case public ones... ;)

Just quickly my highlights:

  • ShadeTree.DomainModel.PersistenceSpecification - extremely fast and elegant way to specify NHibernate mappings. Plus it has all the potential to reduce mapping errors. Just wow! Productivity award!
  • ShadeTree.DomainModel.InMemoryRepository - very elegant way to do caching. Sure, it's so simple, why not think about it as yet another persistence type. Maintainability award!
  • Plus the repository is sprinkled with some very nice abstractions to code generation. Best-reminder-to-do-more-tool-aided-development-again-award. ;)

Go on! Dig into those namespaces yourself. I'll bet you'll find some (good) surprises.

August 5th, 2008 11:37 pm | Comments (0)

Some random links on “Software Factory”

by Tobias Hertkorn on September 15th, 2006

I did some background research on the concept of Software Factories. Unfortunatelly I am running late and therefore here are just some sound bits without lots of explanation:

So much to learn and so little time...

September 15th, 2006 9:07 am | Comments (1)

Code Smell – Database style

by Tobias Hertkorn on May 29th, 2006


I just found a book on Amazon that seems to be the database based equivalent to
Martin Fowler's book. It is called Refactoring Databases : Evolutionary Database Design (Addison Wesley Signature Series) and I just can't wait to get it. If it's as well written as Fowler's book, it will be a great source of information about database design. I don't know about you, but I tend to learn more by reading and understanding bad examples and seeing how somebody fixes those examples.

You will definitifly hear more about it as soon as I've got it in my hands. But the comments on amazon are quite promising.

May 29th, 2006 4:48 pm | Comments (0)

What is “Code Smell”

by Tobias Hertkorn on May 20th, 2006

I bought Fowler's Refactoring a couple of month back. And I just love going back to it and reading chapters again and again. One of the most interesting phrases used in the book is "Coding Smell". And it is way easier to migrate legacy code, when your code is refactored and smells as little as possible. ;)

Today I stumbled across an excellent post concerning Coding Smells at Coding Horror.

To give you a short overview of what Coding Smells are - here is a quote from wikipedia:

In the community of computer programming, code smell is a jargon term used among programmers to refer to a symptom that indicates something may be wrong. It generally indicates that the code should be refactored or the overall design should be reexamined. The term appears to have be coined by Kent Beck on WardsWiki. Usage of the term increased after it was featured in Refactoring. Improving the Design of Existing Code

Determining what is and is not a code smell is often a subject judgment, and will often vary by language, developer and development methodology.

Common Code Smells:

  • Large method - a method, function, or procedure that has grown too large.
  • Large class - a class that has grown too large.
  • Feature envy - a class that uses methods of another class excessively.
  • Inappropriate intimacy - a class that has dependencies on implementation details of another class.
  • Refused bequeath - a class that overrides a method of a base class' such that the contract of the base class is not honored by derived class. See Liskov substitution principle.
  • Lazy class - a class that does too little.

Some links to articles about "Code Smell":

May 20th, 2006 12:23 pm | Comments (1)

The Provider Toolkit

by Tobias Hertkorn on May 6th, 2006

From their website:

The provider model is used throughout ASP.NET 2.0. It is a means of writing each of the technologies used so that new versions can easily be created and plugged in. For example, if you need to access a different database or authentication server, you can create a provider for it. ASP.NET 2.0 will then work with that provider just as it works with the existing features. This makes ASP.NET 2.0 much more flexible, expandable, and customizable than before.

The Provider Toolkit is one of the best sources I came across. Besides a detailed look into the Provider Pattern they are advocating, it features an introduction to the Provider Model and a deep dive on the ASP.NET providers. Great collection of informations for the guys who want it all. ;)

May 6th, 2006 1:52 am | Comments (0)
Tobi + C# = T# - Blogged blogoscoop