3

我有一个用 C# 4.0 编写的 ASP.NET Web 应用程序。应用程序引用了一个带有自己的配置文件的类库。在运行时,类库使用类似于下面的代码来加载这个特定的配置:

var exeConfigPath = this.GetType().Assembly.Location;
var config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);

这样做是因为库必须加载其捆绑配置而不是应用程序配置。应用程序配置不应该关心库的设置,也不应该改变它们。

现在,要让这个概念发挥作用,还需要做一些其他的事情。我必须在属性窗口中将库的配置文件构建操作设置为 Content 并将 Copy 设置为Copy Alwaysor Copy If Newer。到目前为止一切顺利 - 该文件自动进入类库的 bin 目录和 Web 应用程序的 bin 目录,并正确地从App.configto重命名CustomLibrary.dll.config(假设,库的 dll 是 CustomLibrary.dll)。

现在我面临两个问题。

1) 当我将 Web 应用程序发布到文件系统位置(在 IIS 中映射)时,它会CustomLibrary.dll.config显示App.config在已发布应用程序的 bin 文件夹中。好的 - 我将在类库项目中重命名它以匹配预期的约定 - 问题解决了。

2) 即使发布后,IIS 也会再次编译应用程序并将其存储在 ASP.NET 临时文件中。有一个花哨的目录结构,其中包含一个专用于每个引用的程序集的文件夹。CustomLibrary.dll 对应的文件夹中不包含配置文件。由于this.GetType().Assembly.Location将返回临时文件夹的路径,因此应用程序无法加载配置并崩溃。

我需要保留在类库中进行配置的模式,并使其能够在 Web 应用程序中工作。当手动将 .config 复制到临时文件夹时,该应用程序可以工作,但是请看,我真的很讨厌手动复制到随机命名的文件夹。

有没有办法阻止 IIS 使用临时文件夹,或者让它沿着配置文件复制?我相信我面临的问题与配置相关而不是概念性的,因为当配置文件到位时应用程序按预期工作。我也不想在配置文件中使用硬编码的物理路径。


编辑:

为了更清楚,我将指出我想要实现的目标和原因。这个想法是库和 web 项目将作为单独的产品开发 - 在库的配置中不会有用户或应用程序特定的信息,因此它不会因不同的使用场景而改变。它也相当特定于类库功能而不是最终应用程序。将库的配置信息捆绑在其中对我来说是有意义的(类似于 Java,其中 spring 上下文 xml 文件或属性文件与库的 jar 捆绑在一起)。我想避免在消费者应用程序的每个应用程序/网络配置中复制配置。在某些情况下,消费者应用程序是由第三方开发的,而且我不想依赖他们为我的东西做正确的配置。同样,这里唯一的问题是没有将配置文件复制到正确的位置。

4

3 回答 3

1

如果这些是没有人应该看到或更改的静态内部设置,那么将类库中包含的配置文件作为嵌入式资源是否会更好?或者只是一个带有设置的静态类。

这样你就可以确定没有人改变它,在你的场景中这似乎是一个加号。

于 2013-03-15T23:20:28.643 回答
1

我已经采取了一种方法来解决所描述的问题,但对于我的要求来说仍然不是一个非常愉快的问题。

解决方案是利用始终可用的应用程序配置(Web 应用程序中的 web.config 或 app.config)。我已将每个库的配置文件的绝对路径添加为设置。所以我最终得到:

<!--
THIS IS IN THE WEB.CONFIG FILE
-->
<appSettings>
    <add key ="ClassLibrary_ConfigPath"
         value ="{My Publish Output Folder}\ClassLibrary.dll.config"/>
</appSettings>

并且类库现在使用以下代码来加载其配置:

Configuration config = null;
try 
{
    var exeConfigPath = this.GetType().Assembly.Location;
    config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);
}
catch (Exception e)
{
    if (!IsConfigurationNotFoundError(e)) 
    {
        // IsConfigurationNotFoundError logic skipped for brevity
        var exeConfigPath = 
            ConfigurationManager.AppSettings["ClassLibrary_ConfigPath"];
        if (exeConfigPath != null) 
        {
            config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);
        }
    }
    else
    {
        throw;
    }
}

虽然这可行,但如果可能的话,我会等待更好的解决方案。尽管如此,我不必将整个 ClassLibrary.dll.config 复制到 web.config 文件中,但现在我必须管理文件系统位置并注意应用程序设置名称。我真正想要的是 ClassLibrary.dll 的消费者应用程序不以任何方式处理其配置。如果它是一个桌面应用程序,我已经涵盖了这一点,因为 Visual Studio 会适当地复制 ClassLibary.dll.config。我希望有一种方法可以让它在 Web 应用程序中顺利运行。

于 2013-03-15T23:06:42.837 回答
0

简短的回答是:你不能。您必须合并两个配置部分并将所有设置放在应用程序的主配置文件中。如果是 Web 应用程序,它将是web.config. 读这个

于 2013-03-15T01:36:53.950 回答