等效于库(DLL)的“app.config”

是否有一个相当于库(DLL)的app.config ? 如果不是,存储特定于库的configuration设置最简单的方法是什么? 请考虑图书馆可能会用于不同的应用程序。

可以拥有单独的configuration文件,但是您必须手动读取它, ConfigurationManager.AppSettings["key"]将只读取正在运行的程序集的configuration。

假设您将Visual Studio用作IDE,那么可以右键单击所需的项目→添加→新build项目→应用程序configuration文件

这会将App.config添加到项目文件夹,将您的设置放在<appSettings>部分下。

现在从这个文件读取有这样的function:

 string GetAppSetting(Configuration config, string key) { KeyValueConfigurationElement element = config.AppSettings.Settings[key]; if (element != null) { string value = element.Value; if (!string.IsNullOrEmpty(value)) return value; } return string.Empty; } 

并使用它:

 Configuration config = null; string exeConfigPath = this.GetType().Assembly.Location; try { config = ConfigurationManager.OpenExeConfiguration(exeConfigPath); } catch (Exception ex) { //handle errror here.. means DLL has no sattelite configuration file. } if (config != null) { string myValue = GetAppSetting(config, "myKey"); ... } 

您还必须添加对System.Configuration命名空间的引用,才能使ConfigurationManager类可用。

在构build项目时,除了DLL之外,您DllName.dll.config拥有DllName.dll.config文件,这是您必须使用DLL本身发布的文件。

以上是基本示例代码,对于那些对全面示例感兴趣的人,请参阅这个其他答案 。

不幸的是,每个可执行文件只能有一个app.config文件,所以如果你的DLL链接到你的应用程序,他们不能有自己的app.config文件。

解决scheme是:您不需要将App.config文件放在类库的项目中。
您将App.config文件放在引用您的类库dll的应用程序中。

例如,假设我们有一个名为MyClasses.dll的类库,它使用app.config文件,如下所示:

 string connect = ConfigurationSettings.AppSettings["MyClasses.ConnectionString"]; 

现在,假设我们有一个名为MyApp.exe的Windows应用程序,它引用了MyClasses.dll。 它将包含一个带有如下条目的App.config:

 <appSettings> <add key="MyClasses.ConnectionString" value="Connection string body goes here" /> </appSettings> 

要么

一个xml文件最适合于app.config。 根据需要使用xml序列化/反序列化。 你可以把它叫做你想要的。 如果你的configuration是“静态的”,并且不需要改变,你也可以把它作为embedded式资源添加到项目中。

希望它提供一些想法

configuration文件是应用程序范围的,而不是程序集范围的。 所以你需要把你的库的configuration部分放在每个使用你的库的应用程序的configuration文件中。

也就是说,从类库中的应用程序configuration文件,特别是appSettings部分获取configuration不是一个好习惯。 如果你的库需要参数,那么他们应该被作为方法parameter passing给构造函数,工厂方法等等。 这可以防止调用应用程序意外地重用类库所期望的configuration条目。

也就是说,XMLconfiguration文件是非常方便的,所以我发现最好的折衷办法是使用自定义configuration部分。 你可以把你的库的configuration放在一个由框架自动读取和parsing的XML文件中,避免潜在的事故。

您可以在MSDN上了解更多关于自定义configuration部分的信息, Phil Haack也有一篇很好的文章 。

如果您将设置添加到Visual Studio中的类库项目(项目属性,设置),它将使用相关的userSettings / applicatioNSettings部分将app.config文件添加到您的项目中,并从Settings.settings中将这些设置的默认值文件。

然而,这个configuration文件不会在运行时使用 – 而是类库使用其宿主应用程序的configuration文件。

我相信生成这个文件的主要原因是你可以将设置复制/粘贴到宿主应用程序的configuration文件中。

为了回应最初的问题,我通常会将configuration文件添加到我的testing项目中作为链接; 然后可以使用DeploymentItem属性将其添加到testing运行的Out文件夹中。

 [TestClass] [DeploymentItem("MyProject.Cache.dll.config")] public class CacheTest { . . . . } 

为了回应大会不能具体项目的意见,他们可以提供很大的灵活性。 当与国际奥委会框架合作。

 public class ConfigMan { #region Memberes string _assemblyLocation; Configuration _configuration; #endregion #region Constructors /// <summary> /// Loads config file settings for libraries that use assembly.dll.config files /// </summary> /// <param name="assemblyLocation">The full path or UNC location of the loaded file that contains the manifest.</param> public ConfigMan(string assemblyLocation) { _assemblyLocation = assemblyLocation; } #endregion #region Properties Configuration Configuration { get { if (_configuration == null) { try { _configuration = ConfigurationManager.OpenExeConfiguration(_assemblyLocation); } catch (Exception exception) { } } return _configuration; } } #endregion #region Methods public string GetAppSetting(string key) { string result = string.Empty; if (Configuration != null) { KeyValueConfigurationElement keyValueConfigurationElement = Configuration.AppSettings.Settings[key]; if (keyValueConfigurationElement != null) { string value = keyValueConfigurationElement.Value; if (!string.IsNullOrEmpty(value)) result = value; } } return result; } #endregion } 

只是为了做一些事情,我把重要的答案重构成一个class级。 用法是这样的

 ConfigMan configMan = new ConfigMan(this.GetType().Assembly.Location); var setting = configMan.GetAppSetting("AppSettingsKey"); 

程序集没有自己的app.config文件。 他们使用正在使用它们的应用程序的app.config文件。 所以,如果你的程序集期望在configuration文件中有某些东西,那么只要确保你的应用程序的configuration文件里有那些条目即可。

如果您的程序集正在被多个应用程序使用,那么每个应用程序都需要在其app.config文件中包含这些条目。

我build议你做的是定义你的程序集中的类的属性,例如这些值

 private string ExternalServicesUrl { get { string externalServiceUrl = ConfigurationManager.AppSettings["ExternalServicesUrl"]; if (String.IsNullOrEmpty(externalServiceUrl)) throw new MissingConfigFileAppSettings("The Config file is missing the appSettings entry for: ExternalServicesUrl"); return externalServiceUrl; } } 

在这里,ExternalServicesUrl属性从应用程序的configuration文件中获取它的值。 如果任何使用这个程序集的应用程序在configuration文件中缺less这个设置,你将会得到一个exception。

MissingConfigFileAppSettings是一个自定义exception。 你可能想要抛出一个不同的exception。

当然,更好的devise将是这些类的方法提供这些值作为参数,而不是依赖于configuration文件设置。 这样,使用这些类的应用程序就可以决定从哪里以及如何提供这些值。

使用添加现有的项目,从DLL项目中select应用程序configuration。 点击添加之前,使用添加button右侧的向下箭头“添加为链接”

我在开发中一直这样做。

我目前正在为零售软件品牌创build插件,这些品牌实际上是.net类库。 作为一个要求,每个插件需要使用configuration文件进行configuration。 经过一番研究和testing,我编了下面的课。 它完美地完成了这项工作。 请注意,我没有在本例中实现本地exception处理,因为我在更高级别上捕获exception。

一些调整可能需要得到的小数点正确的情况下,小数点和双打,但它适用于我的CultureInfo罚款…

 static class Settings { static UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); static Configuration myDllConfig = ConfigurationManager.OpenExeConfiguration(uri.Path); static AppSettingsSection AppSettings = (AppSettingsSection)myDllConfig.GetSection("appSettings"); static NumberFormatInfo nfi = new NumberFormatInfo() { NumberGroupSeparator = "", CurrencyDecimalSeparator = "." }; public static T Setting<T>(string name) { return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi); } } 

App.Config文件示例

 <add key="Enabled" value="true" /> <add key="ExportPath" value="c:\" /> <add key="Seconds" value="25" /> <add key="Ratio" value="0.14" /> 

用法:

  somebooleanvar = Settings.Setting<bool>("Enabled"); somestringlvar = Settings.Setting<string>("ExportPath"); someintvar = Settings.Setting<int>("Seconds"); somedoublevar = Settings.Setting<double>("Ratio"); 

致暗影向导和马特C

序言 :我使用NET 2.0;

Yiannis Leoussis发布的解决scheme是可以接受的,但是我遇到了一些问题。

首先, static AppSettingsSection AppSettings = (AppSettingsSection)myDllConfig.GetSection("appSettings"); 返回null。 我不得不改变它static AppSettingSection = myDllConfig.AppSettings;

然后return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi); 没有例外情况。 所以我改变了它

 try { return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi); } catch (Exception ex) { return default(T); } 

这工作得很好,但如果你有一个不同的DLL你必须重写每一个程序集的代码。 所以,这是我的一个类的实例,每当你需要的版本。

 public class Settings { private AppSettingsSection _appSettings; private NumberFormatInfo _nfi; public Settings(Assembly currentAssembly) { UriBuilder uri = new UriBuilder(currentAssembly.CodeBase); string configPath = Uri.UnescapeDataString(uri.Path); Configuration myDllConfig = ConfigurationManager.OpenExeConfiguration(configPath); _appSettings = myDllConfig.AppSettings; _nfi = new NumberFormatInfo() { NumberGroupSeparator = "", CurrencyDecimalSeparator = "." }; } public T Setting<T>(string name) { try { return (T)Convert.ChangeType(_appSettings.Settings[name].Value, typeof(T), _nfi); } catch (Exception ex) { return default(T); } } } 

对于configuration:

 <add key="Enabled" value="true" /> <add key="ExportPath" value="c:\" /> <add key="Seconds" value="25" /> <add key="Ratio" value="0.14" /> 

使用它作为:

 Settings _setting = new Settings(Assembly.GetExecutingAssembly()); somebooleanvar = _settings.Setting<bool>("Enabled"); somestringlvar = _settings.Setting<string>("ExportPath"); someintvar = _settings.Setting<int>("Seconds"); somedoublevar = _settings.Setting<double>("Ratio"); 

据我所知,你必须从库.config复制粘贴所需的部分到应用程序.config文件。 每个可执行实例只能获得1个app.config。

我面临同样的问题,并通过添加一个应用程序configuration文件到项目后创build一个静态类参数解决它:

 public static class Parameters { // For a Web Application public static string PathConfig { get; private set; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config"); // For a Class Library public static string PathConfig { get; private set; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "LibraryName.dll.config"); public static string getParameter(string paramName) { string paramValue = string.Empty; using (Stream stream = File.OpenRead(PathConfig)) { XDocument xdoc = XDocument.Load(stream); XElement element = xdoc.Element("configuration").Element("appSettings").Elements().First(a => a.Attribute("key").Value == paramName); paramValue = element.Attribute("value").Value; } return paramValue; } } 

然后得到这样的参数:

 Parameters.getParameter("keyName");