2013-03-01 3 views
2

내 응용 프로그램의 구성을 저장하기 위해 System.Configuration 네임 스페이스 유형을 사용하고 있습니다. 해당 구성의 일부로 원시 형식 컬렉션 (System.Double)을 저장해야합니다.기본 유형이있는 ConfigurationElementCollection

[ConfigurationCollection(typeof(double), AddItemName="TemperaturePoint", 
    CollectionType=ConfigurationElementCollectionType.BasicMap)] 
class DoubleCollection : ConfigurationElementCollection 
{ 
    protected override ConfigurationElement CreateNewElement() 
    { 
     return // Do I need to create a custom ConfigurationElement that wraps a double? 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return // Also not sure what to do here 
    } 
} 

나는이 문제가 발생하는 첫 번째 사람이야 상상도 할 수 있습니다 : 다음과 같은 만들 과잉처럼 보인다. 어떤 아이디어?

답변

3

나는 많은 사용자 정의없이 작동이 얻을 수 있었다합니다. JerKimball의 대답과 비슷하지만 ConfigurationProperty에 TypeConverter 특성을 사용하여 사용자 지정 문자열 처리를 처리하지 않습니다.

using System.Configuration; 
using System.ComponentModel; 

class DomainConfig : ConfigurationSection 
{  

    [ConfigurationProperty("DoubleArray")] 
    [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))] 
    public CommaDelimitedStringCollection DoubleArray 
    { 
     get { return (CommaDelimitedStringCollection)base["DoubleArray"]; } 
    } 
} 

이 사용 방법은 다음과 같습니다 :

내 사용자 지정 설정 섹션 구현

var doubleValues = from string item in configSection.DoubleArray select double.Parse(item); 

그리고 설정 파일 :

<DomainConfig DoubleArray="1.0,2.0,3.0"></DomainConfig> 
3

은 더 명시 적 처리기 "이봐, 내가 여기에 값 목록을 채우고 싶다"없습니다,하지만 당신은 몇 가지 옵션이 있습니다

참조 (요소 수집 등보다 훨씬 간단) 사용자 정의 IConfigurationSectionHandler 구현을 를 통해 :

<configSections> 
    <sectionGroup name="mysection" type="type of handler"/> 
</configSections> 

<mysection> 
    some xml representation of values 
</mysection> 

SingleTagSectionHandler 같은 기존 핸들러 중 하나에 피기 백 - 여기 config 파일에서이 항목에서 값 세트를 추출 털이 보이는 하나의 라이너입니다 :

<configuration> 
    <configSections> 
     <section name="TemperaturePoints" 
      type="System.Configuration.SingleTagSectionHandler" 
      allowLocation="true" 
      allowDefinition="Everywhere"/> 
    </configSections> 

    <TemperaturePoints values="1,2,3,4,5,6,7,8,9,10"/> 
</configuration> 


var values = ((string)((Hashtable)ConfigurationManager 
    .GetSection("TemperaturePoints"))["values"]) 
    .Split(',') 
    .Select(double.Parse); 
,369가

또는 약간의 분할 :

var section = (Hashtable)ConfigurationManager.GetSection("TemperaturePoints"); 
var packedValues = (string)section["values"]; 
var unpackedValues = packedValues.Split(','); 
var asDoubles = unpackedValues.Select(double.Parse).ToArray(); 
1

이 바로 나에게 느끼는 구현입니다.

  • (쉬운 차이점에 대한) 각각 줄 값 잡음에 높은 신호와 부호화
  • 최소 오버 헤드 값

하단에 구비 한정 설명

  • 단순 판독. System.Configuration API의 기본 사항에 대해 더 알고 싶다면 Jon Rista의 Unraveling the Mysteries of .NET 2.0 Configuration 기사 시리즈를 CodeProject.com에 권장합니다. 포이 학습

    의 app.config

    <?xml version="1.0" encoding="utf-8"?> 
    <configuration> 
        <configSections> 
         <section name="strings" 
           type="Sample.StringCollectionConfigSection, SampleAssembly"/> 
         <section name="databases" 
            type="Sample.StringCollectionConfigSection, SampleAssembly"/> 
        </configSections> 
        <strings> 
         <add>dbo.Foo</add> 
         <add>dbo.Bar</add> 
        </strings> 
        <databases> 
         <add>Development</add> 
         <add>Test</add> 
         <add>Staging</add> 
        </databases> 
    </configuration> 
    

    API 사용

    class Program 
    { 
        static void Main(string[] args) 
        { 
         foreach (var s in StringCollectionConfigSection.Named("strings")) 
         { 
          Console.WriteLine(ignoreExpression); 
         } 
         foreach (var d in StringCollectionConfigSection.Named("strings")) 
         { 
          Console.WriteLine(ignoreExpression); 
         } 
        } 
    } 
    

    이행

    using System; 
    using System.Collections.Generic; 
    using System.Configuration; 
    using System.Xml; 
    
    hnamespace Sample 
    { 
        public sealed class StringCollectionConfigSection : ConfigurationSection 
        { 
         public static StringElementCollection Named(string configSection) 
         { 
          var section = (StringCollectionConfigSection)ConfigurationManager.GetSection(configSection); 
          return section.Elements; 
         } 
    
         [ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)] 
         public StringElementCollection Elements 
         { 
          get { return (StringElementCollection)base[""]; } 
          set { base[""] = value; } 
         } 
        } 
    
        [ConfigurationCollection(typeof(StringElement))] 
        public sealed class StringElementCollection : ConfigurationElementCollection, IEnumerable<string> 
        { 
         public StringElement this[int index] 
         { 
          get { return (StringElement)BaseGet(index); } 
          set 
          { 
           if (BaseGet(index) != null) { BaseRemoveAt(index); } 
           BaseAdd(index, value); 
          } 
         } 
    
         public new StringElement this[string key] 
         { 
          get { return (StringElement)BaseGet(key); } 
         } 
    
         protected override ConfigurationElement CreateNewElement() 
         { 
          return new StringElement(); 
         } 
    
         protected override object GetElementKey(ConfigurationElement element) 
         { 
          return ((StringElement)element).Value; 
         } 
    
         public new IEnumerator<string> GetEnumerator() 
         { 
          var enumerator = base.GetEnumerator(); 
          while (enumerator.MoveNext()) 
          { 
           yield return ((StringElement)enumerator.Current).Value; 
          } 
         } 
        } 
    
        public class StringElement : ConfigurationElement 
        { 
         protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) 
         { 
          Value = (string)reader.ReadElementContentAs(typeof(string), null); 
         } 
    
         public string Value {get; private set; } 
        } 
    } 
    

    코드에 대한 nts.

    • app.config에서 구성 섹션의 이름을 정의 할 때 네임 스페이스와 어셈블리 이름을 사용해야합니다.
    • 내 컬렉션에 추가 하위 요소가 필요하지 않았습니다. 문자열 값을 포함하는 요소 만 원했습니다.
      • StringCollectionConfigSection 클래스의 StringElementCollection Elements 특성에 정의 된 ConfigurationPropertyAttribute 내가 달성하고 싶은 디폴트 콜렉션 스타일을 달성하기 위해 빈 이름을 사용합니다. 속성 대신
        <strings> 
            <elements> 
             <add>...</add> 
             <add>...</add> 
            <elements> 
        </strings> 
        
        • StringElementDeserializeElement 날 값과있는 XmlNode의 innerText와를 사용할 수


    • .

    • StringCollectionConfigSectionStringElementCollection Named(string configSection)과 함께 ConfigurationElementCollectionIEnumerator<string> 나에게 내가 원하는 깨끗한 API를 제공합니다.