2010-07-06 3 views
0

데이터베이스에 유지 된 다음 다시 전달되는 다른 클래스의 구성 값 (여러 가지 특수한 논리를 주기적으로 실행하는 작업)이 포함 된 사전이 있습니다. 실행 시간에.Dictionary <string, string>에 대한 강력한 형식의 래퍼를 만드는 가장 좋은 방법

값에 쉽게 액세스 할 수 있고 적절한 형식으로 변환 할 수 있도록 강력하게 형식화 된이 사전의 래퍼를 만들고 싶습니다. 순간

나는 이런 일이이 디자인을 개선 할 수있는 방법이 있는지

public class ConfigurationWrapper { 

    Dictionary<string, string> _configuration; 

    public ConfigurationWrapper(Dictionary<string, string> configuration) { 
     _configuration = configuration; 
     InitializeDefaultValues(); 
    } 

    public virtual GetConfigurationCopy() { 
     return new Dictionary(_configuration); 
    } 

    protected InitializeDefaultValues() { 
     Type t = GetType(); 

     PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(t); 
     foreach (PropertyDescriptor property in properties) { 
      AttributeCollection attributes = property.Attributes; 
      DefaultValueAttribute defaultValue = (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)]; 
      if (defaultValue != null) { 
       if (!Configuration.ContainsKey(property.Name)) { 
       Configuration[property.Name] = Convert.ToString(defaultValue.Value, CultureInfo.InvariantCulture); 
       } 
      } 
     } 
    } 
} 

public class MyTaskConfigurationWrapper : ConfigurationWrapper { 
    private const string MyIntPropertyKey = "MyIntProperty"; 
    [DefaultValue(7)] 
    int MyIntProperty { 
     get { return Convert.ToInt32(_configuration[MyIntPropertyKey], CultureInfo.InvarientCulture); } 
     set { _configuration[MyIntPropertyKey] = value.ToString(CultureInfo.InvarientCulture); } 
    } 

    // More properties of various types. 
} 

내 질문입니다.

내가 고려한 한 가지는 here과 같이 속성의 이름 (따라서 구성 값)을 가져 오기 위해 리플렉션을 사용하는 것입니다. 이렇게하면 문자열 키를 만들지 않아도되고 암시 적으로 키가 속성과 동일한 이름을 갖게됩니다 (이 코드는 InitializeDefaultValues() 코드가 작동하는 데 필요합니다). 그러나이 경우에 해당하는 사실을 모호하게 만듭니다. 특성의 이름이 변경되면 구성 값이 변경됩니다. 따라서 그것은 절충점입니다. 기본 값 속성에 대한 다른 목적이 없다면

// Could alternately use PropertyHelper example with some compile time checking 
protected string GetProperty(MethodBase getMethod) { 
    if (!getMethod.Name.StartsWith("get_") { 
     throw new ArgumentException(
      "GetProperty must be called from a property"); 
    } 
    return _configuration[getMethod.Name.Substring(4)]; 
} 

protected string SetProperty(MethodBase getMethod, string value) { 
    // Similar to above except set instead of get 
} 

[DefaultValue(7)] 
int MyIntProperty { 
    get { return Convert.ToInt32(GetProperty(MethodInfo.GetCurrentMethod(), CultureInfo.InvarientCulture); } 
    set { SetProperty(MethodInfo.GetCurrentMethod(), value.ToString(CultureInfo.InvarientCulture); } 
} 

답변

1

, 나는 전체 반사 접근 방식을 피하고, 대신 수행하는 확장 클래스를 사용하는 것이 값 변환 및 여기서 이것은 다음과 같이 보일 것이다

기본값을 제공 할 수 있습니다. Convert.ToXXX()에 대한 명시적인 호출을 피하기 위해 형식 변환을 직접 확장 메서드에 묶을 수 있습니다.

public static class DictionaryExt 
{ 
    // bundles up safe dictionary lookup with value conviersion... 
    // could be split apart for improved maintenance if you like... 
    public static TResult ValueOrDefault<TKey,TValue,TResult>( 
     this DIctionary<TKey,TValue> dictionary, TKey key, TResult defaultVal) 
    { 
     TValue value; 
     return dictionary.TryGetValue(key, out value) 
      ? Convert.ChangeType(value, typeof(TResult)) 
      : defaultVal; 
    } 
} 

지금 구성 클래스가 될 수있다 :

public class MyTaskConfigurationWrapper : ConfigurationWrapper 
{ 
    private const string MyIntPropertyKey = "MyIntProperty"; 

    int MyIntProperty 
    { 
     // supply the default as a parameter, not reflection attribute 
     get { 
     return _config.ValueOrDefault(MyIntPropertyKey, 7); } 
     set { 
    _config[MyIntPropertyKey] = value.ToString(CultureInfo.InvarientCulture); } 
    } 

    // More properties of various types. 
} 

이 방법을 사용하면 (날짜 시간, 시간 범위, 포인트 등 같은) 편리한 컴파일 시간 표현이없는 유형의 디폴트 값을 제공 할 수 있습니다 . 또한 지저분한 리플렉션 로직을 피할 수 있습니다.

기본 클래스를 통해 기본값에 액세스해야하는 경우 반사/속성 접근 방식을 사용할 수 있습니다. 그러나 심지어, 당신은 단순히 모든 public 속성을 반복하고 생성시 디폴트 값을 가져 오기 위해 getter에 액세스하여 기본값을 사용하여 값 사전을 초기화 할 수 있습니다.

+0

전에 Convert.ChangeType()이 발생하지 않았습니다. 지적 해 주셔서 고맙습니다. 매우 도움이 될 것입니다. 나머지 제안 사항도 유용합니다. –

관련 문제