我下載了Spring.Net源代碼,並且我沒有注意到的第一件事是spring.net核心庫是在.Net framework 2.0中生成的,因爲那個spring.net在當前版本(1.3.2)中不能使用System.Dynamic.ExpandoObject(在.NET Framework 4.0中添加)。
正如我們現在System.Dynamic.ExpandoObject是一個對象,其成員可以在運行時動態添加和刪除,添加的屬性和方法在Dictionary列表中保存。因此,我修改了spring.net核心的源代碼以支持System.Dynamic.ExpandoObject,現在一切正常。
我改變了什麼?
1.我升級Spring.Net庫到.NET框架4.0
2.我修改InitializeNode()方法Spring.Expressions.PropertyOrFieldNode類:
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框架4.0 - 我這樣做是因爲我不喜歡用魔法串comapring對象類型,我更喜歡使用的typeof()
實際上,spring.net正在放棄對<3.5的框架版本的支持。考慮發佈這個問題在他們的問題跟蹤器https://jira.springframework.org/secure/BrowseProject.jspa?id=10020 – Marijn
感謝您的好主意,我在這裏添加此問題https://jira.springsource.org/browse/ SPRNET-1507?page = com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#問題標籤我希望我做出這個正確的,我從來沒有用Jira –
看起來像春天的傢伙喜歡你的解決方案;檢查您的機票下面的評論。 – Marijn