繁体   English   中英

引用程序集的 Visual C# app.config 文件

[英]Visual C# app.config file for a referenced assembly

我们有一个 Visual Studio 2010 解决方案,其中包含几个 C# 项目,符合 Jeffery Palermo 的洋葱架构模式 ( http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ )。 我们有一个 UI 项目,它是一个 ASP.Net MVC 项目,我们有一个名为 Infrastructure 的 C# Class 库项目被 UI 项目引用。 在我们的基础设施项目中,我们添加了一个 app.config 文件来包含特定于基础设施项目的设置。 在运行时,app.config 文件似乎对基础设施项目不可用,只有 web.config 文件包含在 UI 项目中。 我们不想将与基础设施项目相关的设置放入 UI 项目的 web.config 文件中,UI 不需要这些设置。 我们如何使基础架构的 app.config 文件在运行时可用? 我们在想也许我们应该在构建应用程序时放置一个 Post Build Copy 以将 app.config 复制到 UI 目录 - 这是执行此操作的正确方法,还是有更好的方法?

通常,您会被告知无法完成此操作。 但是,您当然可以使用System.Configuration.ConfigurationManager.OpenExeConfiguration方法加载配置文件。 您可以将文件路径传递给程序集(尽管有方法名称,它也不一定是可执行文件)。

当然,这不会将程序集的配置设置合并到正在执行的应用程序的配置设置中,而且我不认为应该这样做。 您的程序集只需要知道它需要通过与System.Configuration.ConfigurationManager.GetSection函数或该类上的静态AppSettings属性不同的机制来检索其设置。

以下是“设置”类的一个非常简单的示例,该类为作为其一部分的装配体加载.config文件。

public static class Settings
{
    public static System.Configuration.Configuration Configuration { get; private set; }

    static Settings()
    {
        // load a .config file for this assembly
        var assembly = typeof(Settings).Assembly;
        Configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(assembly.Location);

        if (Configuration == null)
            throw new System.Configuration.ConfigurationErrorsException(string.Format("Unable to load application configuration file for the assembly {0} at location {1}.", assembly.FullName, assembly.Location));
    }

    // This function is only provided to simplify access to appSettings in the config file, similar to the static System.Configuration.ConfigurationManager.AppSettings property
    public static string GetAppSettingValue(string key)
    {
        // attempt to retrieve an appSetting value from this assembly's config file
        var setting = Configuration.AppSettings.Settings[key];
        if (setting != null)
            return setting.Value;
        else
            return null;
    }
}

还有用法

public class UsageExample
{
    void Usage()
    {
        string mySetting = Settings.GetAppSettingValue("MySetting");

        var section = Settings.Configuration.GetSection("MySection");
    }
}

现在,您仍然必须解决构建问题。 将“应用程序配置文件”(App.config)项目添加到类库程序集确实会导致Visual Studio将其作为.dll.config复制到该程序集的输出文件夹中,但不会自动复制到任何可执行应用程序的输出文件夹中引用那个项目。 因此,您需要添加构建后步骤,以将文件复制到适当的位置,如上所述。

我考虑在类库上执行一个后构建步骤,将.config文件复制到解决方案级别的“ Configurations”文件夹中,然后对可执行项目进行一个后构建步骤,以复制“ Configurations”文件夹中的所有内容到输出文件夹。 我不确定这是否会很好地工作,但是如果这样做的话,您就不会在构建后的步骤中在项目之间创建其他依赖项(这可能会使维护变得困难)。

编辑:最终,您应该考虑这是否真的是您想要做的。 这不是正常的方法,通常可以通过使用提到该问题的其他答案(使用configSource属性)更好地为您服务。

这种方法的缺点可能并不明显,那就是您将无法将第三方组件的设置放入类库的配置文件中,并期望使用它们。 例如,如果您的类库使用log4net,则不能将log4net的设置放入类库的配置文件中,因为log4net组件仍希望从可执行文件的配置文件中加载设置。

即使您后构建复制app.config,它也无法解决您的问题。 该应用程序仍然是Web应用程序,因此配置系统将使用web.config文件。 设置将需要以一种或另一种方式进行。 仍将这些设置保留一些分开的一种方法是将它们放入自定义配置部分,然后将该部分的设置放入单独的文件中。 尽管如此,仍然需要从web.config中引用它(使用configSource属性)。

谢谢威利博士的学徒:我也添加了 function 来获取连接字符串:

public static string GetConnectionStringValue(string key)
{
    var setting = Configuration.ConnectionStrings.ConnectionStrings[key];
    if (setting != null)
        return setting.ConnectionString;
    else
        return null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM