3

現在、ルックアップ テーブルを利用する既存のコードを拡張しています。現在、テーブルには約 25 のエントリがあり、良くも悪くも、キー/値は web.conf の appsettings セクションに格納されています。それらはディクショナリに読み込まれ、アプリケーション全体で使用されます。

ルックアップ テーブルのサイズを約 300 エントリに増やします。これは、このドメインの値の完全なセットです。そのため、これ以上大きくなったり、頻繁に変更されることはありません。このデータを web.conf に保持することが良い考えかどうかはわかりません。データベースはこの実装のオプションではないため、このデータを保存する別の方法を探しています。私の考えのいくつかは次のとおりです。

  • 静的辞書?
  • Xml ファイル (またはその他のフラットな外部データファイル)
  • web.conf の appsettings セクションに残しますか?

私は、データセットを操作するためのメソッドを含むクラスに静的辞書を作成することに傾いています。アドバイス、コメント、怒りの叫びをいただければ幸いです。

4

4 に答える 4

7

appSettings 要素を介して参照される構成ファイルに追加のキーと値のペアを保存できます。これにより、メインの構成ファイルが整理され、追加の構成が独自の依存構成ファイルに保存されます。

これについては、記事MSDN - appSettings Element (General Settings Schema)で説明されています。

これは事実上、2 番目と 3 番目のアイテムの組み合わせです。

メンテナンス上の理由から、コード内の静的辞書には入れません。構成ファイルは、このデータのより明白な場所でもあります。組み込みの .Net 機能を活用することで、たとえば誰かが Xml ファイルを無視するリスクを冒すこともありません。

より具体的な例は次のようになります (ファイル パスはメイン アプリケーションからの相対パスであることに注意してください)。

app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   

   <appSettings file="mykeyvaluepairs.config"/>

</configuration> 

mykeyvaluepairs.config

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>

  <add key="imaginativelynamedkey1" value="imaginativelynamedvalue1" />

</appSettings>

元の app.config では、次のことを行っても問題ないことに注意してください。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   

   <appSettings file="mykeyvaluepairs.config">
       <add key="CanBeOverridenByItemInChildConfigFileWithSameName" value="UnicornsGoHere" />
   </appSettings>

</configuration> 

つまり、mykeyvaluepairs.config ファイルで appsettings を再定義しない限り、両方が並んで存在しますが、mykeyvaluepairs.config 内の同じ名前の項目は、メイン構成内の値をオーバーライドします。

于 2012-05-01T16:19:06.323 に答える
0

Dictionaryコード内でキー/値情報を処理する場合に適しています。構成ファイルをスリムで意味のあるものにしておく方がよいため、300 個のキーと値をすべてそこに置かないでください。XML シリアル化を使用すると、かさばるまたは多数のカスタム設定を別の XML ファイルに簡単に格納 (およびロード) できます。あなたのケースにぴったりのようです。

このコード例を使用して、XML との間でデータを保存/ロードします。

public class KeyValue
{
    public string Key;
    public string Value;
}

static void Save()
{
    // some test data
    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("key1", "value1");
    dict.Add("key2", "value2");
    dict.Add("key3", "value3");
    dict.Add("key4", "value4");

    // convert to List
    List<KeyValue> list1 = (from itm in dict
                            select new KeyValue
                                       {
                                           Key = itm.Key, Value = itm.Value
                                       }).ToList();

    // serialize
    using (StreamWriter sw = new StreamWriter("C:\\temp\\config.xml"))
    {
        XmlSerializer xs = new XmlSerializer(typeof (List<KeyValue>));
        xs.Serialize(sw, list1);
        sw.Close();
    }
}

static void Load()
{
    // deserialize
    using (StreamReader sr = new StreamReader("c:\\temp\\config.xml"))
    {
        XmlSerializer xs = new XmlSerializer(typeof (List<KeyValue>));
        List<KeyValue> list2 = (List<KeyValue>) xs.Deserialize(sr);
        sr.Close();
    }

    // convert to Dictionary
    Dictionary<string, string> dict2 = list2.ToDictionary(x => x.Key, x => x.Value);
}

注: 結果が正しくシリアル化されないKeyValueため、ヘルパー クラスが必要です。dict.ToList()List<KeyValuePair<string,string>>

于 2012-05-03T13:10:08.543 に答える
0

Xml ファイルの例を次に示します。次のように活用します。

string value = MyConfig.Items[key];

新しい値を追加するには:

MyConfig.Write(file => file.Add("newKey", "newValue"));

クラス:

public class MyConfig : IDisposable
{
    string file = "path to file";  // probably in App_Data if this is asp.net
    XElement self;

    public MyConfig()
    {
        if(File.Exists(file))
            self = XElement.Load(file);
        else
            self = new XElement("root");
    }

    public void Add(string key, string value)
    {
        if (!Items.ContainsKey(key))
        {
            self.Add(new XElement("pair",
                new XAttribute("Key", key),
                new XAttribute("Value", value)));
            _Items = null;
        }
    }

    public void Dispose()
    {
        self.Save(file);
    }

    public static Dictionary<string, string> Items
    {
        get
        {
            if (null == _Items)
            {
                _Items = Read.self.Elements().ToDictionary(
                    x => x.Attribute("Key").Value,
                    x => x.Attribute("Value").Value);
            }
            return _Items;
        }
    }
    static Dictionary<string, string> _Items;

    public static MyConfig Read { get { return new MyConfig(); } }
    public static void Write(Action<MyConfig> action)
    {
        using (MyConfig config = new MyConfig())
            action(config);
    }
}

Web サイトはマルチスレッドであるため、_Items 変数に割り当てたり、そこから読み取ったりするときに、_Items 変数をロックしたい場合があります。

于 2012-05-01T16:44:53.147 に答える
0

カプセル化を要求している場合、最善の方法は、必要な値を返すインターフェイスを公開してから、具体的な実装を注入することです。これにより、実装を簡単に変更できます。

実装に行くとき、データが変更されないか、変更が次のリリース用である場合 (基本的に、開発者のみが変更を加えることができる場合)、基になる辞書を使用します (そして、DI コンテナーでシングルトンとして構成します)。さらに、追加のタイプ セーフを提供する列挙値としてキーを保持します。管理者またはビジネスユーザーが何かを構成できない場合、それを外部構成に保持すると、不必要な複雑さが増すだけです。

于 2012-05-01T16:21:19.333 に答える