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

时间:2012-03-18 22:36:32

标签: deployment dll web-config settings app-config

我有一个具有搜索功能的网络应用。搜索算法被编译为单独的dll。在搜索算法的C#代码中,我使用设置文件中保存的字符串指向搜索索引所在的目录。编译完搜索代码后,设置信息将合并到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");

3 个答案:

答案 0 :(得分:5)

最好的办法是直接将配置添加到Web项目中。 .NET并不像您尝试的那样真正支持与库相关的配置;这是设计的。您库的其他用户可能需要不同的配置。将文件标记为应复制到输出文件夹的内容。

编辑:

要执行此操作,请在文件属性中将“Build Action”设置为“Content”,将“Copy to output Directory”设置为“Copy if newer”。您可以使用HttpRuntime.BinDirectory在bin文件夹中发现该文件。您可能希望将此位置传递到库中,而不是让库假设它在Web项目中运行。

或者,只需在web.config中嵌入您需要的配置(配置文件也可以将设置分解为单独的文件)。

最后,您可以考虑将文件嵌入为资源。

编辑:

查看您正在使用的代码,只需将其移至web.config即可。更容易,也更惯用。一旦它在web.config中,只需使用ConfigurationManager.GetSection()来阅读您的部分。

顺便提一下,有一个免费的配置部分设计器,可以非常轻松地创建支持自定义配置部分的类。在这里查看VS Extensions在线图库:

http://visualstudiogallery.msdn.microsoft.com/2a69f74e-83df-4eb0-8cac-cd83b451cd1d?SRC=VSIDE

答案 1 :(得分:5)

理想的方法是从DLL中删除配置依赖项。 dll设计为由应用程序使用,配置属于应用程序而不是dll。

在大多数情况下,你可以通过DI容器或手动编写使用依赖注入来消除依赖于/读取dll代码中的配置。

如果您的搜索dll取决于设置,请将设置作为dll入口点类的依赖项,并继续使用dll代码,假设您的入口点类得到它的设置。

然后,您可以从应用程序提供设置值,无论是web / windows / console还是从配置文件/ db / web service / file system读取。

示例代码:

在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中,但将设置类的实例保留给应用程序。 / p>

答案 2 :(得分: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