diff --git a/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs b/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs index 1014e197..0993cf84 100644 --- a/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs +++ b/src/Spring/Spring.Core/Expressions/PropertyOrFieldNode.cs @@ -24,6 +24,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.Remoting; using System.Runtime.Serialization; @@ -93,6 +94,11 @@ namespace Spring.Expressions { accessor = new ExpandoObjectValueAccessor(memberName); } + // try to initialize node as DynamicObject value + else if (contextType.IsSubclassOf(typeof(System.Dynamic.DynamicObject))) + { + accessor = new DynamicObjectValueAccessor(memberName); + } // try to initialize node as enum value first else if (contextType.IsEnum) { @@ -733,6 +739,56 @@ namespace Spring.Expressions #endregion + #region DynamicObjectValueAccessor implementation + + private class DynamicObjectValueAccessor : BaseValueAccessor + { + private string memberName; + + public DynamicObjectValueAccessor(string memberName) + { + this.memberName = memberName; + } + + public override object Get(object context) + { + var dynamicObject = context as System.Dynamic.DynamicObject; + + try + { + var binder = Microsoft.CSharp.RuntimeBinder.Binder.GetMember( + Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None, + memberName, + dynamicObject.GetType(), + new List + { + Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null) + } + ); + + var callsite = CallSite>.Create(binder); + + return callsite.Target(callsite, dynamicObject); + } + catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException runtimeBinderException) + { + throw new InvalidPropertyException( + typeof(System.Dynamic.DynamicObject), + memberName, + "'" + memberName + "' node cannot be resolved for the specified context [" + context + "].", + runtimeBinderException + ); + } + } + + public override void Set(object context, object value) + { + throw new NotSupportedException("Cannot set the value of an dynamic object."); + } + } + + #endregion + #region TypeValueAccessor implementation private class TypeValueAccessor : BaseValueAccessor