Add support for dynamic objects in spring.net expressions (#195)

This commit is contained in:
anton-feoktistov
2020-11-21 16:27:59 +01:00
committed by GitHub
parent 0b383ee4c9
commit 63f69cacea

View File

@@ -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>
{
Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null)
}
);
var callsite = CallSite<Func<CallSite, object, object>>.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