Adding a dynamic decorator to an object
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:
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:
- public class MyInterceptor : IInterceptor<MyType>
- {
- public void InterceptGetter(IProxy proxy, MyType @object, string propertyName, out object value)
- {
- // do something before get
- proxy.ProceedGetter(propertyName, out value);
- // do something after get
- }
- public void InterceptSetter(IProxy proxy, MyType @object, string propertyName, object value)
- {
- // do something before set
- proxy.ProceedSetter(propertyName, value);
- // do something after set
- m_setterCalled = true;
- }
- private bool m_setterCalled = false;
- public bool SetterWasCalled
- {
- get { return m_setterCalled; }
- }
- }
- public class MyType
- {
- public virtual string Property { get; set; }
- }
- /////// AUTOGENERATED PROXY ///////
- public class MyTypeProxy : MyType, IProxy
- {
- private MyType m_object;
- private IInterceptor<MyType> m_interceptor;
- public MyTypeProxy(MyType @object, IInterceptor<MyType> interceptor)
- {
- m_object = @object;
- m_interceptor = interceptor;
- }
- public override string Property
- {
- get
- {
- object value;
- m_interceptor.InterceptGetter(this, m_object, "Property", out value);
- return (string)value;
- }
- set { m_interceptor.InterceptSetter(this, m_object, "Property", value); }
- }
- public void ProceedGetter(string propertyName, out object value)
- {
- if (propertyName == "Property")
- {
- value = m_object.Property;
- }
- else
- {
- }
- }
- public void ProceedSetter(string propertyName, object value)
- {
- if (propertyName == "Property")
- {
- m_object.Property = (string)value;
- }
- else
- {
- }
- }
- }
- /////// SUPPORTING CODE ///////
- public interface IProxy
- {
- void ProceedGetter(string propertyName, out object value);
- void ProceedSetter(string propertyName, object value);
- }
- public interface IInterceptor<T>
- {
- void InterceptGetter(IProxy proxy, T @object, string propertyName, out object value);
- void InterceptSetter(IProxy proxy, T @object, string propertyName, object value);
- }
- /////// TEST ///////
- public static class Test
- {
- public static void ProxyTest()
- {
- myType.Property = "Test";
- MyType wrappedMyType = GenerateProxy(myType, interceptor);
- wrappedMyType.Property = "Test2";
- Debug.Assert(myType.Property == "Test2");
- Debug.Assert(interceptor.SetterWasCalled);
- }
- // This method belongs in a proxy generator
- private static MyType GenerateProxy(MyType myType, IInterceptor<MyType> interceptor)
- {
- }
- }
Who will help me to adapt the API to the Castle DynamicProxy API and to write the actual proxy/decorator generation? ![]()

AFAIK, this isn’t possible using Castle.
However, a generic way of achieving this sort of behavior, can be achieved by having a wrapper class for property access.
The property assignment wrapper class:
public class PropertyWrapper{
public PropertyWrapper(TType wrappedInstance, Expression<Func> expression, Action beforeAssignProperty)
: this(wrappedInstance, expression, beforeAssignProperty, null)
{
}
public PropertyWrapper(TType wrappedInstance, Expression<Func> expression, Action beforeAssignProperty, Action afterAssignProperty)
{
MemberExpression member = (MemberExpression)expression.Body;
PropertyInfo propertyInfo = (PropertyInfo)member.Member;
ParameterExpression parameterExpression = Expression.Parameter(typeof(TValue), "value");
Expression<Action> setterExpression = Expression.Lambda<Action>
(
Expression.Call(Expression.Constant(wrappedInstance), propertyInfo.GetSetMethod(), parameterExpression),
parameterExpression
);
AssignProperty = setterExpression.Compile();
BeforeAssignProperty = beforeAssignProperty;
AfterAssignProperty = afterAssignProperty;
}
Action AssignProperty { get; set; }
Action BeforeAssignProperty { get; set; }
Action AfterAssignProperty { get; set; }
public void SetProperty(TValue value)
{
if (BeforeAssignProperty != null)
BeforeAssignProperty();
AssignProperty(value);
if (AfterAssignProperty != null)
AfterAssignProperty();
}
}
Then, given the class requiring wrapping:
class SomeClass{
private int _intProp;
public int IntProp
{
get { return _intProp; }
set {
Console.WriteLine("in IntProp");
_intProp = value;
}
}
}
The following code shows how the property is wrapped, and specifying lambda’s to execute before [and after] the property is assigned is made as follows:
SomeClass someInstance = new SomeClass();someInstance.IntProp = 10;
PropertyWrapper intPropWrap = new PropertyWrapper
(
someInstance,
() => someInstance.IntProp,
() => Console.WriteLine("Before"),
() => Console.WriteLine("After")
);
intPropWrap.SetProperty(20);
Console.WriteLine(someInstance.IntProp);
Comment on December 22, 2009 @ 00:05:50
Awesome thinking! Unfortunatelly now the signature of the target object gets completely changed. But your approach certainly gave me something to think about.
Comment on December 22, 2009 @ 15:25:28
“Dynamic Decorator Pattern” describes how to extend functionality of an object at runtime.
Comment on October 5, 2010 @ 17:25:44