0

我試圖將Enterprise Library TypeRegistration ConstructorParameters轉換爲鍵/值對(一般是HashTable或IDictionary)的集合。企業庫 - 從ParameterValue表達式中獲取值

ConstructorParameters屬性是一個IEnumerableOf(ParameterValue),所以我的問題是如何從每個ParameterValue對象中提取值。

每個ParameterValue對象都包含一個Type和一個Expression。

例如,如果一個ParameterValue包含:「EventLoggingEnabled = false」 然後我可以使用expression.Member.Name 獲得密鑰(這是EventLoggingEnabled),但我找不到獲取值(這是「false」)的方法。

有什麼想法?

+1

我想澄清一些事情 - 類型註冊特定於企業庫,並不特定於Unity。 – 2011-05-12 16:27:40

+0

是的,這是正確的(我錯過了,因爲我第一次看到API)。我糾正了問題標題(和消息)。 – 2011-05-14 16:49:22

回答

2

你看過UnityContainerConfigurator的實現嗎?即使你不想使用Unity,你也可以看到在那裏處理類型註冊的東西,並適應Windsor API。

您通常不需要編碼到原始ParameterValue類並通過lambda表達式戳。實際上有三個子類:

  • ConstantParameterValue
  • ContainerResolvedParameter
  • ContainerResolvedEnumerableParameter

的ConstantParameterValue直接給你值作爲.Value屬性。當需要將容器注入參數的值時使用ContainerResolvedParameter,並且在需要注入集合時使用ContainerResolvedEnumerableParameter。 ParameterValue的每個實例實際上都是這些類型之一。

因此,你應該做的是嘗試投射到每一個,然後根據實際類型切換。有一個實用程序基類ParameterValueVisitor,它允許您通過ParameterValues實現訪問者模式,使代碼更加清晰。

所以,我要做的就是放棄採用lambda表達式 - 你不需要做。使用基類來實現訪問者提取所需的信息,然後在具體的類中提供預先消化的信息。查看UnityContainerConfigurator以瞭解如何完成此操作的示例。

+0

我一定會按照你的建議,謝謝。 (在那個特定的項目中,我無法從溫莎轉換到Unity,但這並不意味着我不喜歡它。)再一次,謝謝你的迴應。 – 2011-05-12 20:12:36

+0

好吧,我得到了我的前兩個,通過(或綠色!)整合測試!這是我迄今爲止所做的,https://github.com/moodmosaic/WindsorContainerConfigurator – 2011-05-14 20:57:04

0

這可以工作,當表達式不解析Enumerable。

var dependencies = new Hashtable(); 

     foreach (ParameterValue pv in constructorParameters) 
     { 
      MemberExpression exp = pv.Expression as MemberExpression; 
      if (exp != null) 
      { 
       String key = exp.Member.Name; 
       Object val = GetValue(exp); 

       dependencies.Add(key, val); 
      } 
     } 

    // ... 

    private Object GetValue(MemberExpression member) 
    { 
     var objectMember = Expression.Convert(member, typeof(Object)); 
     var getterLambda = Expression.Lambda<Func<Object>>(objectMember); 

     return getterLambda.Compile().Invoke(); 
    }