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? :)