Question

How to Read app.config and web.config Settings in .NET Class Libraries

csharp.netconfigurationappsettings

Question

I'm working on a C# class library that needs to read settings from either web.config or app.config, depending on whether the DLL is used by an ASP.NET web application or a Windows Forms application.

I found that this works:

ConfigurationSettings.AppSettings.Get("MySetting");

However, Microsoft has marked that API as deprecated.

I also read that I should use this instead:

ConfigurationManager.AppSettings["MySetting"];

But System.Configuration.ConfigurationManager does not seem to be available in my C# class library project.

What is the best way to read configuration values in this situation?

Short Answer

By the end of this page, you will understand how configuration works for .NET class libraries, why ConfigurationSettings is deprecated, how to use ConfigurationManager.AppSettings, and why class libraries usually read configuration from the host application's config file rather than their own separate config file.

Concept

In .NET, a class library does not usually own the application configuration file. The configuration belongs to the host application that loads the library.

That means:

  • A Windows Forms app typically uses app.config
  • An ASP.NET app typically uses web.config
  • Your DLL reads from whichever configuration file belongs to the running application

The important idea is that your library usually does not need to know whether the host is web or desktop. It simply reads configuration through the .NET configuration API, and the runtime resolves the correct host config source.

Older code often uses:

ConfigurationSettings.AppSettings.Get("MySetting")

This API is deprecated. The recommended API in classic .NET is:

ConfigurationManager.AppSettings["MySetting"]

If ConfigurationManager is not available, the usual reason is that your project is missing a reference to the configuration assembly/package.

In classic .NET Framework projects, you typically add a reference to:

System.Configuration

Then import the namespace:

using System.Configuration;

After that, your class library can read values from the host application's configuration.

A common AppSettings entry looks like this:

<appSettings>
  <add key="MySetting" value="Hello" />
</appSettings>

And you read it like this:

string value = ConfigurationManager.AppSettings["MySetting"];

This matters because configuration is one of the main ways applications provide environment-specific values such as:

  • connection strings
  • API endpoints
  • feature flags
  • file paths
  • timeout values

A well-designed library can read config values, but in many real projects it is even better to let the application pass settings into the library explicitly. That makes the library easier to test and reuse.

Mental Model

Think of a class library as a tool used inside a larger machine.

  • The application is the machine
  • The config file is the machine's settings panel
  • The class library is one tool inside the machine

The tool does not carry its own main settings panel. Instead, it reads the settings of the machine that is currently using it.

So if your DLL is loaded by:

  • a web app, it reads the web app's configuration
  • a desktop app, it reads the desktop app's configuration

Your library asks the runtime, "What are the current application settings?" It does not normally ask, "Am I in a web app or a Windows app?"

Take Quiz

Syntax and Examples

The usual approach in a .NET Framework class library is:

using System.Configuration;

public class SettingsReader
{
    public string GetMySetting()
    {
        return ConfigurationManager.AppSettings["MySetting"];
    }
}

Required configuration entry

For a desktop app (app.config) or web app (web.config):

<configuration>
  <appSettings>
    <add key="MySetting" value="Hello from config" />
  </appSettings>
</configuration>

Example with a null check

using System;
using System.Configuration;

public class SettingsReader
{
    public string GetRequiredSetting(string key)
    {
        string value = ConfigurationManager.AppSettings[key];

        if (string.IsNullOrEmpty(value))
        {
            throw new InvalidOperationException($"Missing app setting: {key}");
        }

        return value;
    }
}

This example is safer because missing settings are common in real projects.

If ConfigurationManager is missing

In classic .NET Framework:

  • add a reference to System.Configuration
  • add using System.Configuration;

In newer SDK-style projects, you may need the NuGet package:

System.Configuration.ConfigurationManager

Then this code becomes available:

string value = ConfigurationManager.AppSettings["MySetting"];

Step by Step Execution

Consider this code:

using System;
using System.Configuration;

public class SettingsReader
{
    public void PrintSetting()
    {
        string value = ConfigurationManager.AppSettings["MySetting"];

        if (value == null)
        {
            Console.WriteLine("Setting not found.");
            return;
        }

        Console.WriteLine(value);
    }
}

And this config:

<appSettings>
  <add key="MySetting" value="Blue" />
</appSettings>

Step by step:

  1. The application starts.
  2. The .NET runtime loads the host application's configuration file.
  3. Your class library method PrintSetting() runs.
  4. ConfigurationManager.AppSettings["MySetting"] looks in the host config's <appSettings> section.
  5. If the key exists, it returns the value as a string.
  6. If the key does not exist, it returns null.
  7. The code checks for null.
  8. If found, it prints Blue; otherwise it prints Setting not found.

This is why the library works in both web and desktop apps without separate code paths.

Real World Use Cases

Configuration settings are used everywhere in real applications.

API base URLs

<appSettings>
  <add key="ApiBaseUrl" value="https://api.example.com" />
</appSettings>

A library that calls external services can read this value.

Feature flags

<appSettings>
  <add key="EnableCaching" value="true" />
</appSettings>

A library can enable or disable behavior based on a setting.

File paths

<appSettings>
  <add key="LogFolder" value="C:\Logs" />
</appSettings>

Useful for export tools, logging helpers, or report generators.

Timeouts and limits

<appSettings>
  <add key="RetryCount" value="3" />
</appSettings>

Libraries often need configurable retry counts, batch sizes, or timeout values.

Multi-environment deployment

Different apps can use the same DLL but provide different config values for:

  • development
  • test
  • staging
  • production

That makes the library reusable without code changes.

Take Quiz

Real Codebase Usage

In real projects, developers often go beyond directly reading AppSettings everywhere.

Common pattern: wrap configuration access

Instead of scattering calls to ConfigurationManager.AppSettings throughout the codebase, developers often centralize it:

using System;
using System.Configuration;

public static class AppConfig
{
    public static string GetRequired(string key)
    {
        string value = ConfigurationManager.AppSettings[key];

        if (string.IsNullOrWhiteSpace(value))
        {
            throw new InvalidOperationException($"Missing configuration value: {key}");
        }

        return value;
    }
}

This improves:

  • validation
  • consistency
  • testability
  • error messages

Guard clauses

A common practice is to fail early if config is missing:

string apiUrl = AppConfig.GetRequired("ApiBaseUrl");

This avoids mysterious bugs later.

Parse typed values carefully

AppSettings stores strings, so real codebases often convert them:

int retryCount = int.Parse(ConfigurationManager.AppSettings["RetryCount"]);

A safer version is:

if (!int.TryParse(ConfigurationManager.AppSettings["RetryCount"], out int retryCount))
{
    retryCount = 3;
}

Better design: pass settings into the library

Although a library can read config directly, many teams prefer dependency injection or constructor parameters:

public class EmailService
{
    private readonly string _smtpServer;

    public EmailService(string smtpServer)
    {
        _smtpServer = smtpServer;
    }
}

Then the application reads config and passes it in. This makes the library:

  • easier to test
  • less tightly coupled to configuration APIs
  • easier to reuse in different hosts

Legacy and modern projects

In older .NET Framework codebases, ConfigurationManager is common. In modern .NET applications, configuration is often handled through IConfiguration and JSON files such as appsettings.json. But for app.config and web.config, ConfigurationManager remains the main classic solution.

Common Mistakes

1. Forgetting to add the assembly/package reference

If this fails to compile:

ConfigurationManager.AppSettings["MySetting"];

you may be missing:

  • the System.Configuration reference in .NET Framework
  • or the System.Configuration.ConfigurationManager package in newer projects

2. Forgetting the namespace

Broken code:

public class Test
{
    public string Read()
    {
        return ConfigurationManager.AppSettings["MySetting"];
    }
}

Fix:

using System.Configuration;

3. Assuming the library has its own active config file

Beginners sometimes expect the DLL to automatically use a separate config file. Usually it does not. It reads from the host application's config.

4. Not handling missing keys

Broken code:

string name = ConfigurationManager.AppSettings["UserName"];
Console.WriteLine(name.Length);

If the key is missing, name is null, and this throws an exception.

Safer code:

string name = ConfigurationManager.AppSettings["UserName"];

if (string.IsNullOrEmpty(name))
{
    Console.WriteLine("UserName is missing.");
}
else
{
    Console.WriteLine(name.Length);
}

5. Forgetting that all values are strings

Broken code:

int retryCount = ConfigurationManager.AppSettings["RetryCount"];

Fix:

int retryCount = int.Parse(ConfigurationManager.AppSettings["RetryCount"]);

Safer fix:

int.TryParse(ConfigurationManager.AppSettings["RetryCount"], out int retryCount);

6. Using deprecated ConfigurationSettings

Older code:

ConfigurationSettings.AppSettings.Get("MySetting");

Preferred code:

ConfigurationManager.AppSettings["MySetting"];

7. Hard-coding defaults without documenting them

If a config value is optional, make the fallback clear in code:

string mode = ConfigurationManager.AppSettings["Mode"] ?? "Standard";

Comparisons

ApproachTypical useProsCons
ConfigurationSettings.AppSettings.Get()Older .NET codeWorks in legacy codeDeprecated
ConfigurationManager.AppSettings[]Classic .NET config accessStandard, simple, widely usedReturns only strings
Pass settings into the libraryReusable library designEasier to test and decoupleRequires setup in the host app
IConfigurationModern .NET appsFlexible, strongly integrated with DINot the classic app.config/web.config approach

ConfigurationSettings vs ConfigurationManager

  • Use ConfigurationManager for classic .NET configuration access.
  • Avoid ConfigurationSettings in new or updated code.

Direct config access vs injected settings

StyleGood whenTrade-off
Library reads config directlySmall legacy apps, quick integrationTighter coupling to config system
Application passes settings to libraryClean architecture, testing, reuseSlightly more setup

If you are maintaining an older .NET Framework project, direct use of ConfigurationManager is normal. If you are designing a reusable library, injected settings are often better.

Take Quiz

Cheat Sheet

using System.Configuration;

string value = ConfigurationManager.AppSettings["MySetting"];

Config entry

<configuration>
  <appSettings>
    <add key="MySetting" value="Hello" />
  </appSettings>
</configuration>

Key points

  • ConfigurationSettings is deprecated
  • Use ConfigurationManager.AppSettings[key]
  • Add reference to System.Configuration in .NET Framework
  • In newer projects, you may need the System.Configuration.ConfigurationManager package
  • A class library usually reads from the host application's config file
  • AppSettings values are always strings
  • Missing keys return null

Safe read pattern

string value = ConfigurationManager.AppSettings["MySetting"];

if (string.IsNullOrWhiteSpace(value))
{
    throw new InvalidOperationException("Missing setting: MySetting");
}

Parse numbers safely

int.TryParse(ConfigurationManager.AppSettings["RetryCount"], out int retryCount);

Best practice

  • For simple legacy apps: read via ConfigurationManager
  • For reusable libraries: prefer passing settings into the library when possible

FAQ

How does a class library know whether to use app.config or web.config?

It usually does not need to know. The .NET runtime uses the configuration file of the host application that loads the library.

Why is ConfigurationManager missing in my class library?

Your project is likely missing the required reference or package. In .NET Framework, add System.Configuration. In newer projects, install System.Configuration.ConfigurationManager.

Is ConfigurationSettings.AppSettings.Get() still usable?

It may still work in older projects, but it is deprecated. Prefer ConfigurationManager.AppSettings[...].

Can a DLL have its own separate config file?

Not in the usual automatic way people expect. Typically, the active configuration comes from the host application, not the DLL itself.

What happens if a setting key does not exist?

ConfigurationManager.AppSettings[key] returns null, so your code should handle that safely.

Are app settings strongly typed?

No. Values from AppSettings are strings. You must parse them into int, bool, or other types yourself.

What is the best design for reusable libraries?

Often the best design is for the application to read configuration and pass values into the library, rather than the library reading config directly.

Should I use ConfigurationManager in modern .NET applications?

For classic app.config and web.config, yes. For modern .NET apps, IConfiguration with appsettings.json is more common.

Take Quiz

Mini Project

Description

Build a small configuration reader class for a reusable .NET library. The project demonstrates how a class library reads values from the host application's configuration file and how to validate required settings safely.

Goal

Create a class that reads required and optional application settings using ConfigurationManager and handles missing values cleanly.

Requirements

  • Create a class library class named AppSettingsReader
  • Read one required setting and one optional setting from configuration
  • Throw a clear exception when the required setting is missing
  • Return a default value when the optional setting is missing
  • Show an example app.config or web.config entry
Take Quiz

Keep learning

Related questions

View more