将dll的配置文件移动到调用dll的应用程序中

5
我有一个具备搜索功能的Web应用程序。搜索算法编译为单独的dll文件。在C#代码中,我使用设置文件中保存的字符串来指向搜索索引所在的目录。一旦搜索代码被编译,设置信息将被合并到 Search.dll.config 中,并与 Search.dll 一起放置在 bin 目录下。现在,在我的Web应用程序中,我将 Search.dll 添加到引用中。但是配置文件没有添加到Web应用程序中。然而,Web应用程序可以正常运行并且知道文件的位置。因为在 Settings.Designer 中,它使用 DefaultSettingValueAttribute 来分配默认值(如果配置文件不存在)。
如何将 Search.dll.config 添加到我的Web应用程序中,以便操作员可以根据需要更改服务器上索引文件的位置?
谢谢。
编辑:
我尝试将配置文件添加到我的部署文件夹中。但是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");
3个回答

5
理想的方式是从DLL中移除配置依赖。 DLL旨在由应用程序使用,配置属于应用程序而不属于DLL。
在大多数情况下,您可以通过使用依赖注入(无论是通过DI容器还是手动组合)来消除DLL代码中的依赖/读取配置。
如果您的搜索dll依赖于设置,请将设置作为dll入口点类的依赖项,并假定dll代码假设某种方式获得其设置。
然后,您可以从您的应用程序(Web / Windows / Console)提供设置值,并通过从配置文件/数据库/ 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中,但保留设置类的实例化由应用程序完成。


4
你最好直接将配置添加到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


谢谢!我该如何“将文件标记为应复制到输出文件夹的内容”? - Barka
谢谢!我可以将配置行移动到web.config,但是我的dll如何能够读取web.config呢?看起来asp.net会将它们放在不同的随机命名文件夹中。 - Barka
修改了我的答案以应对这个问题。 - James World

1

以下是您想要做的方法,而不是一些人认为您应该做的方法:

(抱歉,我目前正在使用VB)

假设dll名称为mycompany.mynamespace.dll

  1. 将你的dll项目中的app.config文件重命名为mycompany.mynamespace.dll.config
  2. 在其属性中选择如果较新则复制
  3. 使用以下代码(在dll内部)访问您的设置:

        Dim appConfig = ConfigurationManager.OpenExeConfiguration(Me.GetType.Assembly.Location)
        _WorkingDirectory = appConfig.AppSettings.Settings("WorkingDirectory").Value
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接