2012-04-30 24 views
2

我做對象使用ExpandoObject類,我想那個對象上執行spring.net表達,但後來我得到了以下錯誤:ExpandoObject與Spring表達

'Name' node cannot be resolved for the specified context [System.Dynamic.ExpandoObject].

代碼如下所示:

dynamic expandObject = new ExpandoObject(); 
    expandObject.Name = "Los"; 
    var value = (string)ExpressionEvaluator.GetValue(expandObject, "Name"); 

我認爲春天的表達式不適用於動態對象,但也許你現在爲什麼發生了什麼和任何解決方法(我試圖在IDictionary列表上轉換ExpandoObject,然後執行春季表達式,但這不起作用)?

回答

4

我下載了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()

+0

實際上,spring.net正在放棄對<3.5的框架版本的支持。考慮發佈這個問題在他們的問題跟蹤器https://jira.springframework.org/secure/BrowseProject.jspa?id=10020 – Marijn

+0

感謝您的好主意,我在這裏添加此問題https://jira.springsource.org/browse/ SPRNET-1507?page = com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#問題標籤我希望我做出這個正確的,我從來沒有用Jira –

+0

看起來像春天的傢伙喜歡你的解決方案;檢查您的機票下面的評論。 – Marijn