我下载了 Spring.Net 源代码,我注意到的第一件事是 spring.net 核心库是在 .Net 框架 2.0 中制作的,因为当前版本(1.3.2)的 spring.net 不能与系统一起使用。 Dynamic.ExpandoObject(在 .net framework 4.0 中添加)。
正如我们现在的 System.Dynamic.ExpandoObject 是一个对象,其成员可以在运行时动态添加和删除,添加的属性和方法保存在 Dictionary 列表中。因此,我修改了 spring.net 核心的源代码以支持 System.Dynamic.ExpandoObject,现在一切正常。
我改变了什么?
1. 我将 Spring.Net 库升级到 .NET framework 4.0
2. 我修改了 Spring.Expressions.PropertyOrFieldNode 类中的 InitializeNode() 方法:
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. 我添加了我的自定义 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.");
}
}
编辑:当然,您不必将 spring.net 核心库升级到 .net framework 4.0 - 我这样做是因为我不喜欢通过魔术字符串来组合对象类型,我更喜欢使用 typeof()