在我自己的自定义appSettings上使用foreach所需的代码

jam*_*uss 3 configuration app-config config configuration-files appsettings

我搜索过该网站,并没有找到我正在寻找的确切内容.关闭,但没有雪茄.

基本上我想要一个像这样的配置部分:

    <configSections>
        <section name="PhoneNotificationsSection" type="Alerts.PhoneAlertConfigSection,Alerts,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/>    
    </configSections>
    <PhoneNotificationsSection>
        <phones>
            <add phone="MyMobile" value="1234567890@vtext.com" />
            <add phone="OtherMobile" value="1234567890@txt.att.com" />
        </phones>
    </PhoneNotificationsSection>
Run Code Online (Sandbox Code Playgroud)

然后我想在我的appSettings消费代码中,能够编写这样的东西(伪代码):

foreach (phone p in phones)
{
   //'phone' attribute is just helpful/descriptive
   DoSomething(p.value);
}
Run Code Online (Sandbox Code Playgroud)

我做了足够的研究,知道我可能需要一些自己的类来实现和/或继承某些Configuration类,以使上述代码成为可能.我只是没有发现任何清楚地演示这种情况以及如何编写代码的东西 - 当我尝试学习整个.NET配置世界时,我的大脑开始受到伤害.任何人都有一些像我正在寻找他们可以共享的代码吗?

Mor*_*ner 6

我曾经写过类似的东西,作为C#课程的一个例子.在我看来,它主要演示了.NET配置子系统有多糟糕,尽管代码确实有效.我没有将它改编为你的设置,因为引入错误相当容易,到目前为止SO编辑器没有验证发布的代码示例;)

一,配置部分声明:

<configSections>
    <section name="passwordSafe"
             type="Codeworks.PasswordSafe.Model.Configuration.PasswordSafeSection, Codeworks.PasswordSafe.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>

<passwordSafe hashAlgorithm="SHA256">
    <users>
        <user name="mm" password="Jok2eyBcFs4y7UIAlCuLix4mLfxw2byfvHfElpmk8d8=" />
        <user name="joe" password="Jok2eyBcFs4y7UIAlCuLix4mLfxw2byfvHfElpmk8d8=" />
    </users>
</passwordSafe>
Run Code Online (Sandbox Code Playgroud)

要匹配上面的代码段,我们首先需要配置部分:

public class PasswordSafeSection : ConfigurationSection
{
    #region Static Accessors
    /// <summary>
    /// Gets the configuration section using the default element name.
    /// </summary>
    public static PasswordSafeSection GetSection()
    {
        return GetSection( "passwordSafe" );
    }

    /// <summary>
    /// Gets the configuration section using the specified element name.
    /// </summary>
    public static PasswordSafeSection GetSection( string sectionName )
    {
        PasswordSafeSection section = ConfigurationManager.GetSection( sectionName ) as PasswordSafeSection;
        if( section == null )
        {
            string message = string.Format( "The specified configuration section (<{0}>) was not found.", sectionName );
            throw new ConfigurationErrorsException( message );
        }    
        return section;
    }
    #endregion

    #region Configuration Properties
    [ConfigurationProperty( "hashAlgorithm" )]
    public string HashAlgorithm
    {
        get { return (string) this[ "hashAlgorithm" ]; }
        set { this[ "hashAlgorithm" ] = value; }
    }

    [ConfigurationProperty( "users", IsDefaultCollection=true )]
    public UserElementCollection Users
    {
        get { return (UserElementCollection) this[ "users" ]; }
        set { this[ "users" ] = value; }
    }

    public override bool IsReadOnly()
    {
        return false;
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

我们正在使用自定义元素集合,所以我们也要声明:

[ConfigurationCollection( typeof(UserElement), CollectionType = ConfigurationElementCollectionType.BasicMap )]
public class UserElementCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new UserElement();
    }

    protected override string ElementName
    {
        get { return "user"; }
    }
    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }

    public override bool IsReadOnly()
    {
        return false;
    }

    #region Indexers
    public UserElement this[ int index ]
    {
        get { return BaseGet( index ) as UserElement; }
        set
        {
            if( BaseGet( index ) != null )
            {
                BaseRemoveAt( index );
            }
            BaseAdd( index, value );
        }
    }

    public new UserElement this[ string name ]
    {
        get { return BaseGet( name ) as UserElement; }
    }
    #endregion

    #region Lookup Methods
    protected override object GetElementKey( ConfigurationElement element )
    {
        UserElement user = element as UserElement;
        return user != null ? user.UserName : "error";
    }

    public string GetKey( int index )
    {
        return (string) BaseGetKey( index );
    }
    #endregion

    #region Add/Remove/Clear Methods
    public void Add( UserElement item )
    {
        BaseAdd( item );
    }

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

    public void Remove( UserElement item )
    {
        BaseRemove( GetElementKey( item ) );
    }

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

    public void Clear()
    {
        BaseClear();
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

最后我们需要声明元素集合中使用的自定义元素:

public class UserElement : ConfigurationElement
{
    #region Constructors
    public UserElement()
    {
    }

    public UserElement( string userName, string passwordHash )
    {
        UserName = userName;
        PasswordHash = passwordHash;
    }
    #endregion

    #region Configuration Properties
    [ConfigurationProperty( "name", IsKey = true )]
    public string UserName
    {
        get { return (string) this[ "name" ]; }
        set { this[ "name" ] = value; }
    }

    [ConfigurationProperty( "password", IsRequired = true )]
    public string PasswordHash
    {
        get { return (string) this[ "password" ]; }
        set { this[ "password" ] = value; }
    }

    public override bool IsReadOnly()
    {
        return false;
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

现在,完成所有这些后,我们就可以访问配置文件了.我正在使用Configurator帮助程序类来减少这种麻烦:

public static class Configurator
{
    #region AppSettings Helpers
    public static int SplashScreenDisplayTime
    {
        get { return Convert.ToInt32( ConfigurationManager.AppSettings[ "splash.display.msecs" ] ); }
    }
    #endregion

    #region User Helpers
    public static bool TryGetUserPasswordHash( string userName, out string passwordHash )
    {
        UserElement user = GetUser( userName );
        passwordHash = user != null ? user.PasswordHash : null;
        return ! string.IsNullOrEmpty( passwordHash );
    }

    private static UserElement GetUser( string userName )
    {
        SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
        PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
        return section.Users[ userName ];
    }
    public static void AddUser( string userName, string passwordHash, string encryptionKey )
    {
        SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
        PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
        UserElement user = section.Users[ userName ];
        if( user == null )
        {
            user = new UserElement( userName, passwordHash, encryptionKey );
            section.Users.Add( user );
            config.Save( ConfigurationSaveMode.Modified );
        }
    }
    public static void RemoveUser( string userName )
    {
        SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
        PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
        section.Users.Remove( userName );
        config.Save( ConfigurationSaveMode.Modified );
    }
    public static void UpdateUser( string userName, string passwordHash )
    {
        SystemConfiguration config = GetConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
        PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
        UserElement user = section.Users[ userName ];
        if( user != null )
        {
            user.PasswordHash = passwordHash;
            config.Save( ConfigurationSaveMode.Modified );
        }
    }
    #endregion

    #region Configuration Helpers
    private static SystemConfiguration GetConfiguration( ConfigurationUserLevel userLevel )
    {
        SystemConfiguration config = InitializeConfiguration( userLevel );
        return config;
    }

    private static SystemConfiguration InitializeConfiguration( ConfigurationUserLevel userLevel )
    {    
        SystemConfiguration config = ConfigurationManager.OpenExeConfiguration( userLevel );
        PasswordSafeSection section = config.Sections[ "passwordSafe" ] as PasswordSafeSection;
        if( section == null )
        {
            section = new PasswordSafeSection();
            section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
            section.SectionInformation.ForceSave = true;
            config.Sections.Add( "passwordSafe", section );
            config.Save( ConfigurationSaveMode.Full );
        }
        return config;
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.