カスタム構成を追加する方法(単純なタイプ以上のものが必要な場合)は、ConfigurationSectionを使用することです。その中で、定義したスキーマには、次のように、ConfigurationElementを含むConfigurationElementCollection(名前のないデフォルトのコレクションとして設定)が必要です。 :
public class UserElement : ConfigurationElement
{
[ConfigurationProperty( "firstName", IsRequired = true )]
public string FirstName
{
get { return (string) base[ "firstName" ]; }
set { base[ "firstName" ] = value;}
}
[ConfigurationProperty( "lastName", IsRequired = true )]
public string LastName
{
get { return (string) base[ "lastName" ]; }
set { base[ "lastName" ] = value; }
}
[ConfigurationProperty( "email", IsRequired = true )]
public string Email
{
get { return (string) base[ "email" ]; }
set { base[ "email" ] = value; }
}
internal string Key
{
get { return string.Format( "{0}|{1}|{2}", FirstName, LastName, Email ); }
}
}
[ConfigurationCollection( typeof(UserElement), AddItemName = "user", CollectionType = ConfigurationElementCollectionType.BasicMap )]
public class UserElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new UserElement();
}
protected override object GetElementKey( ConfigurationElement element )
{
return ( (UserElement) element ).Key;
}
public void Add( UserElement element )
{
BaseAdd( element );
}
public void Clear()
{
BaseClear();
}
public int IndexOf( UserElement element )
{
return BaseIndexOf( element );
}
public void Remove( UserElement element )
{
if( BaseIndexOf( element ) >= 0 )
{
BaseRemove( element.Key );
}
}
public void RemoveAt( int index )
{
BaseRemoveAt( index );
}
public UserElement this[ int index ]
{
get { return (UserElement) BaseGet( index ); }
set
{
if( BaseGet( index ) != null )
{
BaseRemoveAt( index );
}
BaseAdd( index, value );
}
}
}
public class UserInfoSection : ConfigurationSection
{
private static readonly ConfigurationProperty _propUserInfo = new ConfigurationProperty(
null,
typeof(UserElementCollection),
null,
ConfigurationPropertyOptions.IsDefaultCollection
);
private static ConfigurationPropertyCollection _properties = new ConfigurationPropertyCollection();
static UserInfoSection()
{
_properties.Add( _propUserInfo );
}
[ConfigurationProperty( "", Options = ConfigurationPropertyOptions.IsDefaultCollection )]
public UserElementCollection Users
{
get { return (UserElementCollection) base[ _propUserInfo ]; }
}
}
UserElementクラスは単純にしていますが、この優れたCodeProjectの記事で説明されているように、各プロパティを完全に宣言するパターンに従う必要があります。ご覧のとおり、これは指定した構成の「ユーザー」要素を表しています。
UserElementCollectionクラスは、実行時にコレクションを変更する場合にコレクションからアイテムを追加/削除/クリアする機能など、複数の「ユーザー」要素を持つことをサポートするだけです。
最後に、「user」要素のデフォルトのコレクションがあることを単に統計するUserInfoSectionがあります。
次は、App.configファイルのサンプルです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup>
<section
name="userInfo"
type="ConsoleApplication1.UserInfoSection, ConsoleApplication1"
allowDefinition="Everywhere"
allowExeDefinition="MachineToLocalUser"
/>
</sectionGroup>
</configSections>
<userInfo>
<user firstName="John" lastName="Doe" email="John.Doe@company.com" />
<user firstName="Jane" lastName="Doe" email="Jane.Doe@company.com" />
</userInfo>
</configuration>
ご覧のとおり、この例では、App.configにいくつかのuserInfo/user要素を含めています。また、マシン/アプリ/ユーザー/移動ユーザーレベルで定義できるように設定を追加しました。
次に、実行時にそれらを更新する方法を知る必要があります。次のコードは例を示しています。
Configuration userConfig = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
var userInfoSection = userConfig.GetSection( "userInfo" ) as UserInfoSection;
var userElement = new UserElement();
userElement.FirstName = "Sample";
userElement.LastName = "User";
userElement.Email = "Sample.User@company.com";
userInfoSection.Users.Add( userElement );
userConfig.Save();
上記のコードは、必要に応じて新しいuser.configファイルを作成し、ユーザーの「ローカル設定\アプリケーションデータ」フォルダーの奥深くに埋め込みます。
代わりに、新しいユーザーをapp.configファイルに追加する場合は、OpenExeConfiguration()メソッドのパラメーターをConfigurationUserLevel.Noneに変更するだけです。
ご覧のとおり、この情報を見つけるには少し掘り下げる必要がありましたが、それはかなり単純です。