2

我在这里搜索了答案。很抱歉,如果之前有人问过这个问题(我怀疑它已经问过了)。

摘要:如何在不复制属性名称的情况下对 web.config 进行强类型调用?


详细信息:在我的代码中,我尽量减少字符串的使用,而且我不喜欢定义两次。

作为对这两个习惯的补充,我将 AppSettings 的使用(及其字符串)限制为一个类,我在整个项目中都引用了它。AppSettings 类公开公共属性:

    12   public static string DateFormatString {
    13       get {
    14           return ConfigurationManager.AppSettings["DateFormatString"];
    15       }
    16   }

如何保留此类并防止属性名称重复(第 12 行和第 14 行)?

或者,您可能会推荐什么其他解决方案?

4

7 回答 7

3

我喜欢使用自定义配置处理程序。

http://haacked.com/archive/2007/03/12/custom-configuration-sections-in-3-easy-steps.aspx

于 2009-06-12T18:59:23.757 回答
2

您的示例中没有重复:一个 DateFormatString 是属性名称,另一个是字符串。您只是遵循将属性命名为与值的查找键相同的约定。

我确实看到了一种可能的改进。您应该在静态构造函数中读取一次配置文件并存储值,而不是在每次访问属性时从 AppSettings 读取它们。

于 2009-06-12T19:28:35.417 回答
1

我可能会建议将 web.config 反序列化为一个对象。然后,您可以访问所有配置条目,就好像它们是属性一样(没有比这更强大的类型了!)

于 2009-06-12T19:01:34.000 回答
1

一种解决方案可能是,

public enum Settings
{
    None,
    DateFormatString,
    DefeaultUserPrefix,
    SomeOtherValue
}

然后有一个助手类,比如,

public static class ConfigurationHelper
{
     public static Get<T>(Settings setting)
     {
         string output = ConfigurationManager.AppSettings[setting.ToString()];
         if(string.isNullOrEmpty(output))
               throw new ConfigurationErrorsException("Setting " + setting + " is not defined in Configuration file.");
         return (T)output; //You can probably use Convert.* functions. 
     }
}

你的调用代码看起来像,

ConfigurationHelper.Get<string>(Settings.DateFormatString);

上述方法提供了某种程度的强类型,但您仍然必须确保配置文件中的设置名称与枚举的名称匹配。

最好的选择是根据配置文件自动生成类。


如果你想要强类型属性,你可以写

public static string DateFormatString
{
    get { return ConfigurationHelper.Get<string>(Settings.DateFormatString); }
}

另外,我建议不要在构造函数中读取配置文件(过早优化?)。如果您在构造函数中读取配置文件,则意味着您无法在应用程序运行时更改配置文件。

于 2009-06-12T19:01:46.760 回答
1

我为不直接属于我的所有内容创建了一个包装器。这包括缓存、会话、配置、外部 Web 服务等。这允许我封装使用该小部件的脏细节。在配置的情况下,我有一个简单的配置类,它公开了我的 app.config 或 web.config 的各种属性。这可能看起来像这样:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using RanchBuddy.Core.Services.Impl;
using StructureMap;

namespace RanchBuddy.Core.Services.Impl
{
    [Pluggable("Default")]
    public class ConfigurationService : IConfigurationService
    {
        internal static int GetDefaultCacheDuration_Days()
        {
            return Convert.ToInt32(ConfigurationManager.AppSettings["DefaultCacheDuration_Days"]);
        }

        ...

        internal static LoggingType GetLoggingType()
        {
            string loggingType = ConfigurationManager.AppSettings["LoggingType"].ToString();
            if(loggingType.ToLower() == "verbose")
            {
                return LoggingType.Verbose;
            }
            else if (loggingType.ToLower() == "error")
            {
                return LoggingType.Error;
            }
            return LoggingType.Error;
        }

        ...

        public static string GetRoot()
        {
            string result = "";
            if(ConfigurationManager.AppSettings["Root"] != null)
            {
                result = ConfigurationManager.AppSettings["Root"].ToString();
            }
            return result;
        }
    }
}

在这里,您可以做的不仅仅是从配置文件中获取值。您可以将字符串转换为所需的类型。您可以使用字符串来确定要返回的枚举值。等等。但关键是任何需要对配置进行的更改都可以在这里进行。如果您想更换配置存储的机制,请包括在内!

于 2009-06-12T19:03:28.020 回答
1

ConfigurationSection使用Configuration Section Designer构建您自己的,这样您根本不必使用AppSettings...但是您将拥有自己的设置集合,甚至在web.config文件中包含 Intellisense。

于 2009-06-12T19:07:50.070 回答
1

我已经编写了一个nuget 包来执行此操作(除其他外)。随附的博客文章详细介绍了详细信息,但此简化片段显示了与您的问题相关的要点。

public string DateFormatString =>
    ConfigurationManager.AppSettings[MethodBase.GetCurrentMethod().Name.Replace("get_", "")];
于 2018-04-07T13:36:22.210 回答