2016-03-31 34 views
0

我想实现第一次创建一个自定义配置部分,我越来越殴打。C#卡住创建自定义配置部分

举个例子,假设我想创建一个自定义的部分,用于存储的CSV文件的列表我的程序读取 - 每个文件,因此它具有:

  • 的路径,该文件
  • 定界符的
  • 甲列表CsvColumn(另一种类型)

然后,每个CsvColumn可具有如特性:

  • 文件中
  • 它的类型

(请忽略这是否是好事,可以通过配置或没有这样做,这只是一个例子,给出一个层次,所以我可以学习如何名称去做这个)。

所以,我创建了以下配置文件:

<configSections> 
    <section name="CsvData" type="CSV_Loader.CsvData, CSV_Loader" /> 
</configSections> 

<CsvData> 
    <CsvFiles> 
     <CsvFile Path="MyPath1" Delimiter=","> 
      <CsvColumn NameInFile="Col1" Type="System.String"/> 
      <CsvColumn NameInFile="Col2" Type="System.String"/> 
      <CsvColumn NameInFile="Col3" Type="System.Double"/> 
     </CsvFile> 
     <CsvFile Path="MyPath2" Delimiter=","> 
      <CsvColumn NameInFile="Col1" Type="System.String"/> 
     </CsvFile> 
    </CsvFiles> 
</CsvData> 

而且,现在我希望建立基于给定here和我越来越可怕卡住的例子/解决方案的定制类。我当前的代码看起来大致如下:

CsvColumn:

public class CsvColumn : ConfigurationElement 
{ 
    [ConfigurationProperty("NameInFile", IsRequired = true, IsKey = true)] 
    public string NameInFile 
    { 
     get { return (string)this["NameInFile"]; } 
    } 

    [ConfigurationProperty("Type", IsRequired = true, DefaultValue = "")] 
    public string Type 
    { 
     get { return (string)this["Type"]; } 
    } 
} 

(仅供参考 - 我想我Type存储为一个实际Type变量,但我以防万一将其设置为String是在这里我的问题是)

CsvFile:

[ConfigurationCollection(typeof(CsvColumn), AddItemName = "CsvColumn", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class CsvFile : ConfigurationElementCollection 
{ 
    [ConfigurationProperty("Path", DefaultValue = "", IsKey = true, IsRequired = true)] 
    public string Path 
    { 
     get { return (string)(base["Path"]); } 
    } 

    [ConfigurationProperty("Delimiter", DefaultValue = ",", IsRequired = true)] 
    public string Delimiter 
    { 
     get { return (string)(base["Delimiter"]); } 
    } 

    public CsvColumn this[int index] 
    { 
     get { return (CsvColumn)BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    public void Add(CsvColumn column) 
    { 
     BaseAdd(column); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new CsvColumn(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((CsvColumn)element).NameInFile; 
    } 

    public void Remove(CsvColumn column) 
    { 
     BaseRemove(column.NameInFile); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(String name) 
    { 
     BaseRemove(name); 
    } 
} 

CsvFile收藏:

[ConfigurationCollection(typeof(CsvFile), AddItemName = "CsvFile", CollectionType = ConfigurationElementCollectionType.BasicMap)] 
public class CsvFiles : ConfigurationElementCollection 
{ 
    public CsvFile this[int index] 
    { 
     get { return (CsvFile)BaseGet(index); } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

    public void Add(CsvFile file) 
    { 
     BaseAdd(file); 
    } 

    public void Clear() 
    { 
     BaseClear(); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new CsvFile(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((CsvFile)element).Path; 
    } 

    public void Remove(CsvFile file) 
    { 
     BaseRemove(file.Path); 
    } 

    public void RemoveAt(int index) 
    { 
     BaseRemoveAt(index); 
    } 

    public void Remove(String name) 
    { 
     BaseRemove(name); 
    } 
} 

CsvData:

public class CsvData : ConfigurationSection 
{ 
    [ConfigurationProperty("CsvFiles")] 
    public CsvFiles CsvFiles 
    { 
     get { return base["CsvFiles"] as CsvFiles; } 
    } 
} 

,我试图调用它在我的代码如下:

var csvData = (ConfigurationManager.GetSection("CsvData") as CsvData); 

但我得到一个ConfigurationExceptionUnrecognized element 'CsvColumn'。 而我不明白为什么。

我的主要问题是:

  1. 我在做什么错?
  2. 有没有更容易(通用)的方式来实现这将使这个过程更容易?

非常感谢!

+1

请给异常的全部细节,而不仅仅是例外名称。 –

+0

@ChrisDunaway,对不起,我有它,但后来忘了发布....我现在将它添加.... –

回答

2

我不知道为什么出现这种情况,可能是一个错误的框架,但是当你有这些嵌套ConfigurationElementCollection情况下,它似乎忽视了AddItemName在内部收集的ConfigurationCollection属性。您可以自己确认,通过将CsvColumn元素更改为add元素,并且它将正确反序列化。

添加下面的构造方法您CsvFile类应该解决您的问题:

public CsvFile() 
    { 
     AddElementName = "CsvColumn"; 
    } 

对于你的第二个问题,你试过图书馆CsvHelper

+0

它正在努力工作!!!!!! - **谢谢!!!! ** - 真的,不能够感谢你! - 这让我坚果! –

+0

至于第二个问题 - 我想知道处理配置文件,而不是CSV文件的通用解决方案...有什么想法吗? –

+0

不客气。我不确定通常处理自定义配置部分。现在,我倾向于避开他们的自己的配置,并将其存储为JSON。 –