PAYATHON 2026

如何在 Class Library Project 中使用 ConfigurationManager

支付阿杰

结论

网站加载 Class Library 后,ConfigurationManager 读取的是宿主网站的 web.config。无需把配置复制到 DLL,也不必在类库中单独维护 app.config。

在经典 ASP.NET / .NET Framework 项目中,只要在类库中引用 System.Configuration,就可以通过 ConfigurationManager.AppSettings 读取配置。

将配置保存在网站的 web.config 中

例如,可以把支付凭据放入 appSettings:

<configuration>
  <appSettings>
    <add key="PaymentMerchantId" value="your-merchant-id" />
    <add key="PaymentApiKey" value="your-api-key" />
  </appSettings>
</configuration>

这些配置应写在网站项目的 web.config 中,不应放在类库项目的配置文件里。网站运行时,DLL 和网站使用同一个应用程序配置上下文,因此类库可以读取宿主网站的配置。

在 Class Library 中使用 ConfigurationManager

如果类库使用 .NET Framework:

  1. 在类库项目中添加对 System.Configuration 程序集的引用。
  2. 在代码中引入命名空间:
using System.Configuration;

然后读取配置:

using System;
using System.Configuration;

public sealed class PaymentService
{
    public void MakePayment(decimal amount)
    {
        string merchantId =
            ConfigurationManager.AppSettings["PaymentMerchantId"];

        string apiKey =
            ConfigurationManager.AppSettings["PaymentApiKey"];

        if (string.IsNullOrWhiteSpace(merchantId))
        {
            throw new ConfigurationErrorsException(
                "Missing appSettings key: PaymentMerchantId");
        }

        if (string.IsNullOrWhiteSpace(apiKey))
        {
            throw new ConfigurationErrorsException(
                "Missing appSettings key: PaymentApiKey");
        }

        // 使用 merchantId、apiKey 和 amount 调用支付接口。
    }
}

部署后,ConfigurationManager 会读取网站根目录下实际生效的 web.config。DLL 是否放在 bin 目录中,不会影响这一行为。

更易维护的设计:由网站传入配置

让类库直接依赖 web.config 是可行的,但这会增加类库与宿主环境的耦合。为了便于测试和维护,可以由网站读取配置,再通过构造函数传给支付服务。

类库代码:

public sealed class PaymentOptions
{
    public string MerchantId { get; set; }
    public string ApiKey { get; set; }
}

public sealed class PaymentService
{
    private readonly PaymentOptions _options;

    public PaymentService(PaymentOptions options)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }

        if (string.IsNullOrWhiteSpace(options.MerchantId))
        {
            throw new ArgumentException(
                "MerchantId is required.",
                nameof(options));
        }

        if (string.IsNullOrWhiteSpace(options.ApiKey))
        {
            throw new ArgumentException(
                "ApiKey is required.",
                nameof(options));
        }

        _options = options;
    }

    public void MakePayment(decimal amount)
    {
        // 使用 _options.MerchantId 和 _options.ApiKey 调用支付接口。
    }
}

网站中的初始化代码:

using System.Configuration;

var options = new PaymentOptions
{
    MerchantId = ConfigurationManager.AppSettings["PaymentMerchantId"],
    ApiKey = ConfigurationManager.AppSettings["PaymentApiKey"]
};

var paymentService = new PaymentService(options);
paymentService.MakePayment(100.00m);

采用这种方式后,类库不需要关心配置来自 web.config、环境变量,还是其他密钥存储服务。

如果使用 .NET Core 或现代 .NET

在 ASP.NET Core 中,不推荐使用 System.Configuration.ConfigurationManager 管理配置。通常的做法是使用 Microsoft.Extensions.Configuration 和依赖注入,将配置绑定到选项对象,再注入类库。

只有需要兼容旧式配置文件时,才考虑安装 System.Configuration.ConfigurationManager NuGet 包。应根据网站和类库的目标框架选择配置方式,不能只看 DLL 如何部署。

注意事项

  • 类库中的 app.config 通常不会随 DLL 单独生效,最终使用的是宿主应用程序的配置。
  • 不要将生产凭据写死在代码中,也不要把它们提交到源代码仓库。
  • 不要在日志、异常信息或支付请求的调试信息中输出完整密钥。
  • 生产环境可以考虑使用受保护的配置节、环境变量或专用密钥管理服务。
  • 如果网站部署在 Web Farm 或多个实例上,需要保证每个实例都能取得一致且正确的凭据。
  • 应在启动时检查必需配置是否存在,避免等到真实支付发生时才发现配置缺失。

备注:内容仅供参考。