将 dll 的配置文件移动到调用 dll 的应用程序
Posted
技术标签:
【中文标题】将 dll 的配置文件移动到调用 dll 的应用程序【英文标题】:moving the config files for a dll to the app that calls the dll 【发布时间】:2012-04-03 12:16:32 【问题描述】:我有一个具有搜索功能的网络应用程序。搜索算法被编译成一个单独的 dll。在搜索算法的 C# 代码中,我使用设置文件中保存的字符串来指向搜索索引所在的目录。编译搜索代码后,设置信息将包含在Search.dll.config
中,该Search.dll.config
与Search.dll 一起放在bin 目录中。现在在我的 Web 应用程序中,我将 Search.dll 添加到引用中。配置文件未添加到 Web 应用程序中。但是,Web 应用程序运行良好并且知道文件在哪里。因为在Settings.Designer
内部,如果配置文件不存在,它使用DefaultSettingValueAttribute
分配默认值。
如何将Search.dll.config
也添加到我的网络应用程序中,以便操作员可以根据需要更改服务器上索引文件的位置?
谢谢
编辑:
我尝试将配置文件添加到我的部署文件夹。但是 ASP.NET 将 dll 放在 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root...... 的目录中,并且配置文件不会被复制到那里。所以此时我不知道如何在我的代码中包含配置文件。
感谢您的帮助。
注意:
我一直在使用以下代码将配置文件的值导入应用程序。但是,它取决于dll和配置文件在同一个文件夹中,我不知道如何完成。
var executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var location = executingAssembly.Location; //C:\MyApp\bin\Debug\Search.dll
var config = ConfigurationManager.OpenExeConfiguration(location);
var sections = config.Sections; //count of this is 21
ConfigurationSectionGroup csg = config.GetSectionGroup("applicationSettings");
ConfigurationSectionCollection csc = csg.Sections;
ConfigurationSection cs = csc.Get("Search.Properties.Settings");
【问题讨论】:
【参考方案1】:以下是你如何做你想做的事,而不是一些人认为你应该做的事:
(对不起,我现在在 vb 工作)
假设 dll 被命名为 mycompany.mynamespace.dll
-
将 dll 项目中的 app.config 文件重命名为 mycompany.mynamespace.dll.config
在其属性中,说 Copy If Newer
使用此代码(在 dll 中)访问您的设置:
Dim appConfig = ConfigurationManager.OpenExeConfiguration(Me.GetType.Assembly.Location)
_WorkingDirectory = appConfig.AppSettings.Settings("WorkingDirectory").Value
【讨论】:
【参考方案2】:理想的方法是从 DLL 中删除配置依赖项。 dll 是为应用程序设计的,配置属于应用程序而不是 dll。
在大多数情况下,您可以通过 DI 容器或通过手动 compose 使用依赖注入来摆脱对 dll 代码中配置的依赖/读取。
如果您的搜索 dll 依赖于设置,请将设置作为您的 dll 入口点类的依赖项,并假设您的入口点类以某种方式获取它的设置,然后继续执行 dll 代码。
然后,您可以从应用程序中提供设置值,无论是 web/windows/console 还是从配置文件/db/web 服务/文件系统中读取。
示例代码:
在 dll 中:
public interface ISearcherDirectorySettings
string[] SearchIndexPointers get;
public class Searcher
private readonly ISearcherDirectorySettings _searchDirctorySettings;
public Searcher(ISearcherDirectorySettings searchDirtorySettings)
_searchDirctorySettings = searchDirtorySettings;
public void SearchAlgorithm()
var indexes = _searchDirctorySettings.SearchIndexPointers;
// search code
在您的应用程序中:
public class SearcherDirectorySettings : ISearcherDirectorySettings
private readonly string[] _pointers;
public SearcherDirectorySettings(string[] pointers)
_pointers = pointers;
public string[] SearchIndexPointers
get return _pointers;
public class ApplicationRootClass //Owns configuration file
const string FirstPointerKey = "File1";
const string SecondPointerKey = "File2";
private Func<string, string> _getFromConfig = key => ConfigurationManager.AppSettings[key];
public ApplicationRootClass()
var searcherDirectorySettings = new SearcherDirectorySettings(new[] _getFromConfig(FirstPointerKey),_getFromConfig(SecondPointerKey) );
var searcher = new Searcher(searcherDirectorySettings);
searcher.SearchAlgorithm();
有了这个,你可以实现“快速失败”。您可以在任何应用程序中使用搜索 dll,应用程序负责提供设置值。
如果您最终在多个应用程序/项目中使用 dll 并复制设置类代码,请使用实用程序组件来完成这项工作或将设置类移动到 dll 中,但将设置类的实例化留给应用程序。
【讨论】:
【参考方案3】:最好的办法是直接将配置添加到 Web 项目中。 .NET 并不真正支持您尝试的方式与库关联的配置;这是设计使然。您库的其他用户可能需要不同的配置。将文件标记为应复制到输出文件夹的内容。
编辑:
为此,在文件属性中将“构建操作”设置为“内容”并将“复制到输出目录”设置为“如果较新则复制”。您可以使用HttpRuntime.BinDirectory
发现 bin 文件夹中的文件。您可能希望将此位置传递给您的库,而不是让库假定它在 Web 项目中运行。
或者,只需在 web.config 中嵌入您需要的配置(配置文件也可以将设置分解为单独的文件)。
最后,您可以考虑将文件嵌入为资源。
编辑:
查看您正在使用的代码,只需将其移至 web.config。容易得多,而且惯用语。一旦它在 web.config 中,只需使用 ConfigurationManager.GetSection()
阅读您的部分。
顺便说一句,有一个免费的配置部分设计器,可以非常轻松地创建支持自定义配置部分的类。在此处查看 VS 扩展在线图库:
http://visualstudiogallery.msdn.microsoft.com/2a69f74e-83df-4eb0-8cac-cd83b451cd1d?SRC=VSIDE
【讨论】:
谢谢!如何“将文件标记为应复制到输出文件夹的内容。”? 谢谢!我可以将配置行移至 web.config,但我的 dll 将如何读取 web.config?似乎 asp.net 将它们放在不同的随机命名的文件夹中。 编辑了我的答案来处理这个问题。以上是关于将 dll 的配置文件移动到调用 dll 的应用程序的主要内容,如果未能解决你的问题,请参考以下文章
需要如何帮助将 system.serviceModel 配置部分移动到我的代码中