3

.NET構成APIを使用してカスタム構成セクションを作成しています。2つのサブ要素のうちの1つだけを持つことができるセクションを定義したいのですが、

例えば

<MyCustomSection>
    <myItems>
        <myItemType name="1">
            <firstSubTypeConfig />
        </myItemType>
        <myItemType name="2">
            <secondSubTypeConfig />
        </myItemType>
    </myItems>
</MyCustomSection>

現在、次のように定義されたセクションがあります。

public class MyCustomSection : ConfigurationSection
{
    public override bool IsReadOnly()
    {
        return false;
    }

    [ConfigurationProperty("myItems")]
    public MyItemsCollection MyItems 
    { 
        get { return (MyItemsCollection)base["myItems"]; }
        set { base["myItems"] = value; }
    }
}

[ConfigurationCollection(typeof(MyItemType), AddItemName="myItemType",
    CollectionType=ConfigurationElementCollectionType.BasicMap)]
public class MyItemsCollection : ConfigurationElementCollection
{
    public override bool IsReadOnly()
    {
        return false;
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }

    protected override string ElementName
    {
        get { return "myItemType"; }
    }

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

    protected override object GetElementKey(ConfigurationElement element)
    {
        return (element as MyItemType).Name;
    }
}


public class MyItemType : ConfigurationElement
{
    public override bool IsReadOnly()
    {
        return false;
    }

    [ConfigurationProperty("name", IsRequired=true)]
    public string Name 
    { 
        get { return (string)base["name"]; }
        set { base["name"] = value; }
    }

    [ConfigurationProperty("firstSubTypeConfig")]
    public FirstSubTypeConfig FirstSubTypeConfig 
    { 
        get { return (FirstSubTypeConfig)base["firstSubTypeConfig"]; }
        set { base["firstSubTypeConfig"] = value; }

    }

    [ConfigurationProperty("secondSubTypeConfig")]
    public SecondSubTypeConfig SecondSubTypeConfig 
    { 
        get { return (SecondSubTypeConfig)base["secondSubTypeConfig"]; }
        set { base["secondSubTypeConfig"] = value; }
    }
}

public class FirstSubTypeConfig : ConfigurationElement
{
    public override bool IsReadOnly()
    {
        return false;
    }
}

public class SecondSubTypeConfig : ConfigurationElement
{
    public override bool IsReadOnly()
    {
        return false;
    }
}

構成もプログラムで変更および保存されます。現在、構成セクションを保存すると、firstSubTypeConfig要素のみを指定した場合でも、secondSubTypeConfig要素が追加されます。

FirstSubTypeConfig私の最初の考えは、との共通基本クラスを導入することSecondSubTypeConfigでしたが、構成APIがそれを処理するかどうかまたはどのように処理するかはわかりません。

相互に排他的なカスタム構成要素を設定するにはどうすればよいですか?

4

2 に答える 2

1

これが「正しい」アプローチかどうかはわかりませんが、これは機能します。

質問に書かれているコードは、設定ファイルを正常にロードします。プロパティをチェックしてElementInformation.IsPresent、正確に1つの要素が含まれていることを検証できます。

例えば

var custom = (MyCustomSection)ConfigurationManager.GetSection("MyCustomSection");
foreach (MyItemType itemType in custom.MyItems)
{
    if (itemType.FirstSubTypeConfig.ElementInformation.IsPresent 
        && itemType.SecondSubTypeConfig.ElementInformation.IsPresent)
    {
        throw new ConfigurationErrorsException("At most one of firstSubTypeConfig or secondSubTypeConfig can be specified in a myItemType element");
    }
    else if (!itemType.FirstSubTypeConfig.ElementInformation.IsPresent
        && !itemType.SecondSubTypeConfig.ElementInformation.Ispresent)
    {
        throw new ConfigurationErrorsException("Either a firstSubTypeConfig or a secondSubTypeConfig element must be specified in a myItemType element");
    }
}

設定の保存に関しては、チェックしElementInformation.IsPresentて明示的に設定するnullと、要素が設定ファイルに書き込まれなくなるようです。例えば

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var custom = (MyCustomSection)config.GetSection("MyCustomSection");

//make modifications against the custom variable ...

foreach (MyItemType itemType in custom.MyItems)
{
    if (!itemType.FirstSubTypeConfig.ElementInformation.IsPresent)
        itemType.FirstSubTypeConfig = null;
    if (!itemType.SecondSubTypeConfig.ElementInformation.IsPresent)
        itemType.SecondSubTypeConfig = null;  
}

config.Save();
于 2012-12-14T00:27:08.197 に答える
0

これは、ビジネスロジックではなくPostDeserialize、クラスから取得したメソッドで行う必要があると思います。ConfigurationElement

例えば:

protected override void PostDeserialize()
{
    base.PostDeserialize();
    if (FirstSubTypeConfig != null && SecondTypeCOnfig != null)
    {
        throw new ConfigurationErrorsException("Only an element is allowed.");
    }
}
于 2019-10-03T14:21:58.240 に答える