I downloaded Spring.Net source code, and the first thing I notcied is that spring.net core library is made in .Net framework 2.0, because of that spring.net in current version(1.3.2) can t work with System.Dynamic.ExpandoObject(added in .net framework 4.0).
As we now System.Dynamic.ExpandoObject is an object whose member can be dynamically added and removed at run time, added properties and methods are hold in Dictionary list. Therfore I modified source code of spring.net core to support System.Dynamic.ExpandoObject and now everything s works perfectly.
What have I changed?
1. I Upgraded Spring.Net library to .NET framework 4.0
2. I Modified InitializeNode() method in Spring.Expressions.PropertyOrFieldNode class:
private void InitializeNode(object context)
{
Type contextType = (context == null || context is Type ? context as Type : context.GetType());
if (accessor == null || accessor.RequiresRefresh(contextType))
{
memberName = this.getText();
// clear cached member info if context type has changed (for example, when ASP.NET page is recompiled)
if (accessor != null && accessor.RequiresRefresh(contextType))
{
accessor = null;
}
// initialize this node if necessary
if (contextType != null && accessor == null)
{//below is new IF;)
if (contextType == typeof(System.Dynamic.ExpandoObject))
{
accessor = new ExpandoObjectValueAccessor(memberName);
}
// try to initialize node as enum value first
else if (contextType.IsEnum)
{
try
{
accessor = new EnumValueAccessor(Enum.Parse(contextType, memberName, true));
}
catch (ArgumentException)
{
// ArgumentException will be thrown if specified member name is not a valid
// enum value for the context type. We should just ignore it and continue processing,
// because the specified member could be a property of a Type class (i.e. EnumType.FullName)
}
}
// then try to initialize node as property or field value
if (accessor == null)
{
// check the context type first
accessor = GetPropertyOrFieldAccessor(contextType, memberName, BINDING_FLAGS);
// if not found, probe the Type type
if (accessor == null && context is Type)
{
accessor = GetPropertyOrFieldAccessor(typeof(Type), memberName, BINDING_FLAGS);
}
}
}
// if there is still no match, try to initialize node as type accessor
if (accessor == null)
{
try
{
accessor = new TypeValueAccessor(TypeResolutionUtils.ResolveType(memberName));
}
catch (TypeLoadException)
{
if (context == null)
{
throw new NullValueInNestedPathException("Cannot initialize property or field node " +
memberName +
" because the specified context is null.");
}
else
{
throw new InvalidPropertyException(contextType, memberName,
" " + memberName +
" node cannot be resolved for the specified context [" +
context + "].");
}
}
}
}
}
2. I Added my custom ExpandoObjectValueAccessor
private class ExpandoObjectValueAccessor : BaseValueAccessor
{
private string memberName;
public ExpandoObjectValueAccessor(string memberName)
{
this.memberName = memberName;
}
public override object Get(object context)
{
var dictionary = context as IDictionary<string, object>;
object value;
if (dictionary.TryGetValue(memberName, out value))
{
return value;
}
throw new InvalidPropertyException(typeof(System.Dynamic.ExpandoObject), memberName,
" " + memberName +
" node cannot be resolved for the specified context [" +
context + "].");
}
public override void Set(object context, object value)
{
throw new NotSupportedException("Cannot set the value of an expando object.");
}
}
EDIT:当然,你不需要升级。 网上核心图书馆净额 4.0 - 我之所以这样做,是因为我不喜欢用魔法调取物体类型,我更喜欢使用(a)类。