Equivalent to 'app.config' for a library (DLL)
对于库(dll),是否有等同于
您可以有单独的配置文件,但是您必须"手动"读取它,
假设您使用的是Visual Studio作为IDE,则可以右键单击所需的项目→添加→新建项→应用程序配置文件。
号
这会将
现在要从该文件中读取,必须具有以下功能:
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
并使用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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"); ... } |
为了使configurationManager类可用,还必须添加对System.Configuration命名空间的引用。
在构建项目时,除了dll之外,您还将拥有
以上是基本的示例代码,对于那些对全比例示例感兴趣的人,请参考另一个答案。
不幸的是,每个可执行文件只能有一个app.config文件,因此如果您的应用程序中链接了dll,它们就不能有自己的app.config文件。
解决方案是:您不需要将app.config文件放入类库的项目中。将app.config文件放入引用类的应用程序中图书馆的DLL。
例如,假设我们有一个名为myclasses.dll的类库,使用app.config文件,如下所示:
1 2 | string connect = ConfigurationSettings.AppSettings["MyClasses.ConnectionString"]; |
现在,假设我们有一个名为myapp.exe的Windows应用程序,引用myclasses.dll。它将包含一个app.config,其中包含一个这样的条目AS:
1 2 3 | <add key="MyClasses.ConnectionString" value="Connection string body goes here" /> </appSettings> |
或
XML文件最适合app.config。使用XML序列化/反序列化为需要。你可以随心所欲地称呼它。如果配置为"静态"而且不需要更改,您也可以将其作为嵌入的资源。
希望它能给你一些建议
配置文件是应用程序范围,而不是程序集范围。因此,您需要将库的配置部分放在使用库的每个应用程序的配置文件中。
也就是说,从应用程序的配置文件(特别是类库中的
也就是说,XML配置文件非常方便,所以我发现的最佳折衷方法是使用自定义配置部分。您可以将库的配置放在一个XML文件中,该文件由框架自动读取和解析,从而避免潜在的事故。
您可以在msdn上了解有关自定义配置部分的更多信息,而且PhilHaack有一篇关于它们的好文章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public class ConfigMan { #region Members string _assemblyLocation; Configuration _configuration; #endregion Members #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 Constructors #region Properties Configuration Configuration { get { if (_configuration == null) { try { _configuration = ConfigurationManager.OpenExeConfiguration(_assemblyLocation); } catch (Exception exception) { } } return _configuration; } } #endregion Properties #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 Methods } |
为了做点什么,我把最上面的答案重构成一个类。用法如下:
1 2 | ConfigMan configMan = new ConfigMan(this.GetType().Assembly.Location); var setting = configMan.GetAppSetting("AppSettingsKey"); |
如果在Visual Studio中将设置添加到类库项目中(项目属性、设置),它将向项目中添加app.config文件,其中包含相关的usersettings/applicationsettings部分,以及settings.settings文件中这些设置的默认值。
但是,这个配置文件不会在运行时使用,而是类库使用其宿主应用程序的配置文件。
我认为生成此文件的主要原因是为了将设置复制/粘贴到宿主应用程序的配置文件中。
为了回答最初的问题,我通常将测试项目中的配置文件作为链接添加;然后可以使用deploymentem属性将其添加到测试运行的out文件夹中。
1 2 3 4 5 6 7 8 9 | [TestClass] [DeploymentItem("MyProject.Cache.dll.config")] public class CacheTest { . . . . } |
对于大会不能是特定于项目的评论,他们可以并且它提供了很大的灵活性,特别是在与国际奥委会框架合作时。
我也遇到了同样的问题,在向项目中添加应用程序配置文件后,创建了一个静态类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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; } } |
然后得到这样的参数:
1 | Parameters.GetParameter("keyName"); |
前言:我使用的是NET 2.0;
伊安妮丝·利奥西斯的解决方案是可以接受的,但我有一些问题。
首先,
那么,
1 2 3 4 5 6 7 8 | try { return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi); } catch (Exception ex) { return default(T); } |
这是非常好的工作,但如果您有一个不同的DLL,您必须重写每次代码为每个程序集。所以,这是我的版本,每次需要的时候都可以实例化一个类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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); } } } |
配置:
1 |
使用它作为:
1 2 3 4 5 6 | 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"); |
我目前正在为一个零售软件品牌创建插件,它实际上是.NET类库。作为一项要求,每个插件都需要使用配置文件进行配置。经过一点研究和测试,我编了下节课。它完美地完成了工作。注意,在我的案例中,我没有实现本地异常处理,因为我在更高的级别捕获异常。
可能需要进行一些调整,以使小数点正确,以防出现小数和双精度,但它对我的文化很有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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文件示例
1 |
用途:
1 2 3 4 | somebooleanvar = Settings.Setting<bool>("Enabled"); somestringlvar = Settings.Setting<string>("ExportPath"); someintvar = Settings.Setting<int>("Seconds"); somedoublevar = Settings.Setting<double>("Ratio"); |
影子向导信用&;mattc
使用"添加现有项",从dll项目中选择应用程序配置。单击"添加"之前,请使用"添加"按钮右侧的小箭头"添加为链接"
在我的开发团队里,我总是这样做。
程序集没有自己的app.config文件。它们使用正在使用它们的应用程序的app.config文件。因此,如果程序集希望在配置文件中包含某些内容,那么只需确保应用程序的配置文件中包含这些条目即可。
如果您的程序集正由多个应用程序使用,那么每个应用程序都需要在其app.config文件中包含这些条目。
我建议您做的是为这些值在程序集中的类上定义属性,例如
1 2 3 4 5 6 7 8 9 10 | 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从应用程序的配置文件中获取其值。如果使用此程序集的任何应用程序在配置文件中缺少该设置,那么您将得到一个异常,很明显是丢失了某些内容。
MissingConfigFileAppSettings是一个自定义异常。您可能想抛出一个不同的异常。
当然,更好的设计是将这些类的方法作为参数提供这些值,而不是依赖配置文件设置。这样,使用这些类的应用程序就可以决定它们提供这些值的位置和方式。
从配置中使用必须非常容易,如下所示:
1 2 3 4 5 6 7 8 | var config = new MiniConfig("setting.conf"); config.AddOrUpdate("port","1580"); if (config.TryGet("port", out int port)) // if config exist { Console.Write(port); } |
有关详细信息,请参阅miniconfig
为什么不使用:
- c用
[ProjectNamespace].Properties.Settings.Default.[KeyProperty] 。# - 用于vb.net的
My.Settings.[KeyProperty]
您只需在设计时通过以下方式直观地更新这些属性:
据我所知,您必须将library.config中所需的部分复制并粘贴到applications.config文件中。每个可执行实例只能获得1个app.config。