2014-09-21 3 views
0

동적으로로드되는 유형의 동적 런타임 구성을 사용하는 시스템이 있습니다.BeanUtils to .NET

시스템이 XML을 기반으로 유형을로드하고 인스턴스를 생성합니다. 그런 다음 XML 파일에서 "속성"을 읽고 생성 된 인스턴스에서 이러한 속성을 설정합니다. 현재이 인스턴스는 인스턴스의 단순한 속성에서 직접 작동하지만 호출하는 부분에서 알 수없는 설정 계층 구조를 가질 수 있습니다.

자바 BeanUtils [http://commons.apache.org/proper/commons-beanutils/]]과 비슷한 유틸리티 라이브러리를 찾고 있습니다. 나는이 (의사 코드) 같은 것을 할 수 있기를 원하는 것 :

Util.SetProperty(someInstance, "property1.property2, someValue); 

아니면 확장자 :

someInstance.SetProperty("property1.property2, someValue); 

그리고 물론 Get에 반대합니다.

BeanUtils에는 속성을 설명하는 고유 한 스타일이 있으므로 목록을 비롯한 대부분의 유형의 속성에 사용할 수 있습니다.

문제에 대한 다른 접근 방법에 대한 의견이 있으신가요?

답변

0

목록, 사전 및 중첩 된 속성을 지원하는 도우미 클래스는 매우 드물지만 여러 인덱서를 지원해야하는 경우 확장해야합니다. (여러 인덱스)

 var a = new A { PropertyB = new B() }; 
     Helper.SetProperty(a, "PropertyB.Value", 100); 
     var value = Helper.GetProperty(a, "PropertyB.Value"); 

인덱서 :

public enum Qwerty 
    { 
     Q,W,E,R,T,Y 
    } 

    class A 
    { 
     private int[,] _array=new int[10,10]; 

     public B PropertyB { get; set; } 

     public int this[int i, int j] 
     { 
      get { return _array[i, j]; } 
      set { _array[i, j] = value; } 
     } 
    } 

    class B 
    { 
     public int Value { get; set; } 
    } 

중첩 된 속성 :

 var a = new A { PropertyB = new B() }; 
     Helper.SetProperty(a, "Item[1,1]", 100); 
     var value = Helper.GetProperty(a, "Item[1,1]"); 

리스트 : 여기

public static class Helper 
{ 
    public static void SetProperty(object instance, string propery, object value) 
    { 
     const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
     var properties = propery.Split('.'); 
     var type = instance.GetType(); 
     object[] index = null; 
     PropertyInfo property = null; 

     for (var i = 0; i < properties.Length; i++) 
     { 
      var indexValue = Regex.Match(properties[i], @"(?<=\[)(.*?)(?=\])").Value; 

      if (string.IsNullOrEmpty(indexValue)) 
      { 
       property = type.GetProperty(properties[i], flags); 
       index = null; 
      } 
      else 
      { 
       property = 
        type.GetProperty(properties[i].Replace(string.Format("[{0}]", indexValue), string.Empty), 
         flags); 
       index = GetIndex(indexValue, property); 
      } 

      if (i < properties.Length - 1) 
       instance = property.GetValue(instance, index); 
      type = instance.GetType(); 
     } 

     property.SetValue(instance, value, index); 
    } 

    public static object GetProperty(object instance, string propery) 
    { 
     const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
     var properties = propery.Split('.'); 
     var type = instance.GetType(); 

     foreach (var p in properties) 
     { 
      var indexValue = Regex.Match(p, @"(?<=\[)(.*?)(?=\])").Value; 

      object[] index; 
      PropertyInfo property; 
      if (string.IsNullOrEmpty(indexValue)) 
      { 
       property = type.GetProperty(p, flags); 
       index = null; 
      } 
      else 
      { 
       property = 
        type.GetProperty(p.Replace(string.Format("[{0}]", indexValue), string.Empty), 
         flags); 
       index = GetIndex(indexValue, property); 
      } 

      instance = property.GetValue(instance, index); 
      type = instance.GetType(); 
     } 

     return instance; 
    } 

    private static object[] GetIndex(string indicesValue, PropertyInfo property) 
    { 
     var parameters = indicesValue.Split(','); 
     var parameterTypes = property.GetIndexParameters(); 
     var index = new object[parameterTypes.Length]; 

     for (var i = 0; i < parameterTypes.Length; i++) 
      index[i] = parameterTypes[i].ParameterType.IsEnum 
       ? Enum.Parse(parameterTypes[i].ParameterType, parameters[i]) 
       : Convert.ChangeType(parameters[i], parameterTypes[i].ParameterType); 

     return index; 
    } 
} 

몇 가지 예입니다

 var list = new List<int>() { 0, 1, 2, 3, 4 }; 
     Helper.SetProperty(list, "Item[2]", 200); 
     var value = Helper.GetProperty(list, "Item[2]"); 

목록과 중첩 된 속성 :

 var list = new List<A>() { new A { PropertyB = new B() } }; 
     Helper.SetProperty(list, "Item[0].PropertyB.Value", 75); 
     var value = Helper.GetProperty(list, "Item[0].PropertyB.Value"); 

사전 : 키와 같은 열거와

 var dic = new Dictionary<int, A> { { 100, new A { PropertyB = new B() } } }; 
     var newA = new A { PropertyB = new B() { Value = 45 } }; 
     Helper.SetProperty(dic, "Item[100]", newA); 
     var value = Helper.GetProperty(dic, "Item[100].PropertyB.Value"); 

사전 : 값으로

var dic = new Dictionary<Qwerty, A> { { Qwerty.Q, new A { PropertyB = new B() } } }; 
    var newA = new A { PropertyB = new B() { Value = 45 } }; 
    Helper.SetProperty(dic, "Item[Q]", newA); 
    var value = Helper.GetProperty(dic, "Item[Q].PropertyB.Value"); 

열거 :

var list = new List<Qwerty>() { Qwerty.Q, Qwerty.W, Qwerty.E, Qwerty.R, Qwerty.T, Qwerty.Y }; 
    Helper.SetProperty(list, "Item[2]", Qwerty.Q); 
    var value = Helper.GetProperty(list, "Item[2]"); 
+0

안녕하세요, 코드 주셔서 감사합니다. 내가 찾을 수 있다고 생각한 것을 찾을 수 없을 때 나는 항상 조금 의심스러워한다. 종류는 해결책이 필요한 문제가 아니라는 것을 나타냅니다. 하지만 대안을 찾을 수 없으므로 코드를 작성해 보겠습니다. 고마워. – gurun