物理ファイルは、最も一般的に使用される当社のオリジナル設定のキャリアで、最適な設定ファイルのフォーマットは、三つの主要で構成、彼らはJSON、XMLやINI、対応するコンフィギュレーション・ソースのタイプですJsonConfigurationSource、XmlConfigurationSourceとIniConfigurationSourceです。しかし、.NETのコア構成システムのために、我々はそれが固有の欠点を持っている、ためには、実際に付与された理想的な構成のXMLソースではなく、少なくともJSON比較取る、それはデータ構造の集合のサポートです満足のいくものではありません。[この記事では、「に同期されたASP.NETフレームワークコアの秘密の中で」]
まず、なぜコンフィギュレーションのためのXMLのエレガントなコレクションで表現することが困難です
で、「構成モデル詳細設計、」我々は、構成モデルを設計し、実装する用紙が詳細に記載されています。この記事では、アプリケーションの設定を反映していると言う私は、構成ツリー「リーフノード」ベアラによって固有の構成データ「構成ツリー」、それを呼び出すように、階層のツリーです。コンフィギュレーション・データが辞書にロードした後、異なるソースから変換されたとき、私はそれが「辞書の設定」を呼び出します すべてのデータおよびその構造の「構成ツリー」を格納できる「辞書の設定」をするために、我々は、コンフィギュレーション・辞書、パス、および直接キーと値の辞書の要素として、リーフノードの値にすべてのリーフノードを格納する必要があります。ツリー内の各ノードの構成を必要と辞書は、ユニークなパスを持っている必要があるので、キーがユニークです。データ構造の問題のXmlConfigurationSource / XmlConfigurationProviderもサポートされていないセットは、ここに発生します。
1:パブリッククラスのプロフィール
2:{
3:公共性別性別{取得します。セットする; }
4:公共int型の年齢{取得します。セットする; }
5:公共のContactInfoのContactInfo {取得します。セットする; }
6:}
7:
8:パブリッククラスのContactInfo
9:{
10:公共の文字列のEmailAddress {取得します。セットする; }
11:公共の文字列PHONENO {取得します。セットする; }
12:}
13:
14:公共列挙性別
15:{
16:男性、
17:女性
18:}
簡単な例として、オブジェクトプロフィール(上記で示した定義されたタイプのプロファイル)のセットを表すと仮定必要XMLは、我々は、自然に、以下の構成を採用します。
1:<プロファイル>
2:<プロフィール性別= "男性" 年齢= "18">
3:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "123" />
4:</プロフィール>
5:<プロフィール性別= "男性" 年齢= "25">
6:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "456" />
7:</プロフィール>
8:<プロフィール性別= "男性" 年齢= "40">
9:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "789" />
10:</プロフィール>
それは、以下に示す「構成ツリー」マッピングされるように、このXML構造のために、XmlConfigurationProviderは「ブルート」方法を使用します。この構成ノード名としてXML要素名に直接ツリーので、ツリーのルート三個のプロフィールオブジェクトは「プロファイル」は、疑いを命名することであるため、ツリーは、表現するために辞書を使用することができるためではないだろうそれは、すべてのノードが別のパスを持っていることを保証することはできません。
第二に、XML構成ツリー構造変換の要件に応じて、わずかに
後者は(括弧内の定義を使用して)、これらの2つのデータ型の方法の明確な定義を提供するので、それは、コレクション又はアレイの非常に自然な形でXML JSON形式として表現することができない理由が、唯一のXMLの子要素コンセプトは、我々はそれが子要素のコレクションがあるかどうかを判断することはできません。あなたは仮定を作る場合:同じXML要素内のすべてのサブ要素が同じ名前を持っている場合は、私たちが集まりとみなすことができます。このような仮説によると、私たちは少しXML変換はデータ構造の集合を表すために困難な問題を解決することができますXmlConfigurationSource。
私たちは、暫定的にExtendedXmlConfigurationSourceそれを名付け、XmlConfigurationSourceはConfigurationSourceの新しいタイプを作成導き出します。ConfigurationProvdier型XmlConfigurationSource XmlConfigurationProvider由来するExtendedXmlConfigurationProvider、を提供します。オーバーライドLoadメソッドでは、元のXML構造によってExtendedXmlConfigurationProviderことにより、元の法的XML(同じ名前を持つXML要素)を収集するために構成辞書に変換することができる可能に応じて変化します。以下の図は、変換に用いられるXMLルールと手順の構成を示しています。
上記のように、XMLの元のセットを変換するための構造は、2つのステップで構成されました。最初のステップは、「名前のXML要素を追加する要素の集まりであるappend_indexプロパティ」(属性)を、我々は、プロパティの値としてゼロベースのインデックスを採用しています。第2のステップは、変換の最初のステップの結果に基づいて、新しいXMLを作成するであろう(例えば<概要>など)は、同じ名前の要素の集合は、(例えば、<付加価値に基づく指標として、新しい名前になりprofile_index_0 >)。ほかのオブジェクトのコレクションを表すことができるXMLを変換は間違いありません。以下に示すようExtendedXmlConfigurationProviderは、上述した変換論理が書き換えLoadメソッドで具現、定義されています。
1:パブリッククラスExtendedXmlConfigurationProvider:XmlConfigurationProvider
2:{
3:公共ExtendedXmlConfigurationProvider(XmlConfigurationSource源):ベース(ソース)
4:{}
5:
6:公共オーバーライドボイドロード(ストリームstream)
7: {
8://ソースファイルをロードし、XmlDocumentオブジェクトを作成します
9:常にXmlDocument sourceDoc =新規のXmlDocument()。
10:sourceDoc.Load(ストリーム)。
11:
12://インデックスを追加
13:this.AddIndexes(sourceDoc.DocumentElement)。
14:
15://追加インデックスに従って新しいXmlDocumentオブジェクトを作成します。
16:常にXmlDocument newDoc =新規のXmlDocument()。
17:のXmlElementにdocumentElement = newDoc.CreateElement(sourceDoc.DocumentElement.Name)。
18:newDoc.AppendChild(にdocumentElement)。
19:
20:foreachの(sourceDoc.DocumentElement.ChildNodesでのXMLELEMENT要素)
21:{
22:this.Rebuild(要素、にdocumentElement、
23:名=> newDoc.CreateElement(名));
24:}
25:
26://新しいXmlDocumentの初期設定辞書の下で
27:使用する(ストリームnewstreamに=新しいのMemoryStream())
28:{
29:使用する(したXmlWriterライター= XmlWriter.Create(newstreamに))
30:{
31:newDoc.WriteTo(作家);
32:}
33:newStream.Position = 0。
34:base.Load(newstreamに)。
35:}
36:}
37:
38:プライベート無効AddIndexes(のXmlElement要素)
39:{
40:(。element.ChildNodes.OfTypeは<のXmlElement>()、COUNT()> 1)場合
41:{
42:もし(element.ChildNodes.OfType <のXmlElement>()GROUPBY(それ=> it.Name).Count()== 1)
43:{
44:INTインデックス= 0。
45:foreachの(element.ChildNodesでのXmlElementサブ要素)
46:{
47:subElement.SetAttribute(。 "append_index"、(インデックス++)のToString());
48:AddIndexes(サブ要素)。
49:}
50:}
51:}
52:}
53:
54:プライベート無効の再構築(のXmlElementソース、のXmlElement destParent、のFunc <文字列、のXmlElement>クリエイター)
55:{
56:文字列インデックス= source.GetAttribute( "append_index")。
57:文字列がelementName = string.IsNullOrEmpty(インデックス)?source.Name:$ "{} source.Name _index_ {}インデックス"。
58:のXMLELEMENT要素=クリエーター(がelementName)。
59:destParent.AppendChild(要素)
60:foreachの(source.AttributesでXmlAttribute属性)
61:{
62:もし(!attribute.Name = "append_index")
63:{
64:element.SetAttribute(attribute.Name、attribute.Value)。
65:}
66:}
67:
68:foreachの(source.ChildNodesでのXMLELEMENTサブ要素)
69:{
70:再構築(サブ要素、要素、クリエーター)
71:}
72:}
73:}
物理ファイルは、最も一般的に使用される当社のオリジナル設定のキャリアで、最適な設定ファイルのフォーマットは、三つの主要で構成、彼らはJSON、XMLやINI、対応するコンフィギュレーション・ソースのタイプですJsonConfigurationSource、XmlConfigurationSourceとIniConfigurationSourceです。しかし、.NETのコア構成システムのために、我々はそれが固有の欠点を持っている、ためには、実際に付与された理想的な構成のXMLソースではなく、少なくともJSON比較取る、それはデータ構造の集合のサポートです満足のいくものではありません。[この記事では、「に同期されたASP.NETフレームワークコアの秘密の中で」]
まず、なぜコンフィギュレーションのためのXMLのエレガントなコレクションで表現することが困難です
で、「構成モデル詳細設計、」我々は、構成モデルを設計し、実装する用紙が詳細に記載されています。この記事では、アプリケーションの設定を反映していると言う私は、構成ツリー「リーフノード」ベアラによって固有の構成データ「構成ツリー」、それを呼び出すように、階層のツリーです。コンフィギュレーション・データが辞書にロードした後、異なるソースから変換されたとき、私はそれが「辞書の設定」を呼び出します すべてのデータおよびその構造の「構成ツリー」を格納できる「辞書の設定」をするために、我々は、コンフィギュレーション・辞書、パス、および直接キーと値の辞書の要素として、リーフノードの値にすべてのリーフノードを格納する必要があります。ツリー内の各ノードの構成を必要と辞書は、ユニークなパスを持っている必要があるので、キーがユニークです。データ構造の問題のXmlConfigurationSource / XmlConfigurationProviderもサポートされていないセットは、ここに発生します。
1:パブリッククラスのプロフィール
2:{
3:公共性別性別{取得します。セットする; }
4:公共int型の年齢{取得します。セットする; }
5:公共のContactInfoのContactInfo {取得します。セットする; }
6:}
7:
8:パブリッククラスのContactInfo
9:{
10:公共の文字列のEmailAddress {取得します。セットする; }
11:公共の文字列PHONENO {取得します。セットする; }
12:}
13:
14:公共列挙性別
15:{
16:男性、
17:女性
18:}
簡単な例として、オブジェクトプロフィール(上記で示した定義されたタイプのプロファイル)のセットを表すと仮定必要XMLは、我々は、自然に、以下の構成を採用します。
1:<プロファイル>
2:<プロフィール性別= "男性" 年齢= "18">
3:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "123" />
4:</プロフィール>
5:<プロフィール性別= "男性" 年齢= "25">
6:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "456" />
7:</プロフィール>
8:<プロフィール性別= "男性" 年齢= "40">
9:<のContactInfoのEmailAddress = "[email protected]" PHONENO = "789" />
10:</プロフィール>
それは、以下に示す「構成ツリー」マッピングされるように、このXML構造のために、XmlConfigurationProviderは「ブルート」方法を使用します。この構成ノード名としてXML要素名に直接ツリーので、ツリーのルート三個のプロフィールオブジェクトは「プロファイル」は、疑いを命名することであるため、ツリーは、表現するために辞書を使用することができるためではないだろうそれは、すべてのノードが別のパスを持っていることを保証することはできません。
第二に、XML構成ツリー構造変換の要件に応じて、わずかに
後者は(括弧内の定義を使用して)、これらの2つのデータ型の方法の明確な定義を提供するので、それは、コレクション又はアレイの非常に自然な形でXML JSON形式として表現することができない理由が、唯一のXMLの子要素コンセプトは、我々はそれが子要素のコレクションがあるかどうかを判断することはできません。あなたは仮定を作る場合:同じXML要素内のすべてのサブ要素が同じ名前を持っている場合は、私たちが集まりとみなすことができます。このような仮説によると、私たちは少しXML変換はデータ構造の集合を表すために困難な問題を解決することができますXmlConfigurationSource。
私たちは、暫定的にExtendedXmlConfigurationSourceそれを名付け、XmlConfigurationSourceはConfigurationSourceの新しいタイプを作成導き出します。ConfigurationProvdier型XmlConfigurationSource XmlConfigurationProvider由来するExtendedXmlConfigurationProvider、を提供します。オーバーライドLoadメソッドでは、元のXML構造によってExtendedXmlConfigurationProviderことにより、元の法的XML(同じ名前を持つXML要素)を収集するために構成辞書に変換することができる可能に応じて変化します。以下の図は、変換に用いられるXMLルールと手順の構成を示しています。
上記のように、XMLの元のセットを変換するための構造は、2つのステップで構成されました。最初のステップは、「名前のXML要素を追加する要素の集まりであるappend_indexプロパティ」(属性)を、我々は、プロパティの値としてゼロベースのインデックスを採用しています。第2のステップは、変換の最初のステップの結果に基づいて、新しいXMLを作成するであろう(例えば<概要>など)は、同じ名前の要素の集合は、(例えば、<付加価値に基づく指標として、新しい名前になりprofile_index_0 >)。ほかのオブジェクトのコレクションを表すことができるXMLを変換は間違いありません。以下に示すようExtendedXmlConfigurationProviderは、上述した変換論理が書き換えLoadメソッドで具現、定義されています。
1:パブリッククラスExtendedXmlConfigurationProvider:XmlConfigurationProvider
2:{
3:公共ExtendedXmlConfigurationProvider(XmlConfigurationSource源):ベース(ソース)
4:{}
5:
6:公共オーバーライドボイドロード(ストリームstream)
7: {
8://ソースファイルをロードし、XmlDocumentオブジェクトを作成します
9:常にXmlDocument sourceDoc =新規のXmlDocument()。
10:sourceDoc.Load(ストリーム)。
11:
12://インデックスを追加
13:this.AddIndexes(sourceDoc.DocumentElement)。
14:
15://追加インデックスに従って新しいXmlDocumentオブジェクトを作成します。
16:常にXmlDocument newDoc =新規のXmlDocument()。
17:のXmlElementにdocumentElement = newDoc.CreateElement(sourceDoc.DocumentElement.Name)。
18:newDoc.AppendChild(にdocumentElement)。
19:
20:foreachの(sourceDoc.DocumentElement.ChildNodesでのXMLELEMENT要素)
21:{
22:this.Rebuild(要素、にdocumentElement、
23:名=> newDoc.CreateElement(名));
24:}
25:
26://新しいXmlDocumentの初期設定辞書の下で
27:使用する(ストリームnewstreamに=新しいのMemoryStream())
28:{
29:使用する(したXmlWriterライター= XmlWriter.Create(newstreamに))
30:{
31:newDoc.WriteTo(作家);
32:}
33:newStream.Position = 0。
34:base.Load(newstreamに)。
35:}
36:}
37:
38:プライベート無効AddIndexes(のXmlElement要素)
39:{
40:(。element.ChildNodes.OfTypeは<のXmlElement>()、COUNT()> 1)場合
41:{
42:もし(element.ChildNodes.OfType <のXmlElement>()GROUPBY(それ=> it.Name).Count()== 1)
43:{
44:INTインデックス= 0。
45:foreachの(element.ChildNodesでのXmlElementサブ要素)
46:{
47:subElement.SetAttribute(。 "append_index"、(インデックス++)のToString());
48:AddIndexes(サブ要素)。
49:}
50:}
51:}
52:}
53:
54:プライベート無効の再構築(のXmlElementソース、のXmlElement destParent、のFunc <文字列、のXmlElement>クリエイター)
55:{
56:文字列インデックス= source.GetAttribute( "append_index")。
57:文字列がelementName = string.IsNullOrEmpty(インデックス)?source.Name:$ "{} source.Name _index_ {}インデックス"。
58:のXMLELEMENT要素=クリエーター(がelementName)。
59:destParent.AppendChild(要素)
60:foreachの(source.AttributesでXmlAttribute属性)
61:{
62:もし(!attribute.Name = "append_index")
63:{
64:element.SetAttribute(attribute.Name、attribute.Value)。
65:}
66:}
67:
68:foreachの(source.ChildNodesでのXMLELEMENTサブ要素)
69:{
70:再構築(サブ要素、要素、クリエーター)
71:}
72:}
73:}