Question

So let me start off by saying "I know this isn't a best practice" and that I do not want to add the information from the app.config files to the web.config file... I've got a project that is a class library itself and it will be using a lot of class libraries as well.

Typically in my unit test project (used for testing) or my web project (that uses the lib in production) I have to add all of the configuration information. These libraries aren't going to be called differently from each project so I'm looking for a way to get the calling project to read the callee project's config file.

I've looked online and the only two things I've found so far are:

1) Don't do it. You need to add the information to the calling project's config file

example a) Read from App.config in a Class Library project

example b) Class Library project in ASP.NET reading from web.config and not app.config

example c) .Net app.config in library project

2) You shouldn't do it but I know how (no how to included :/)

example a) app.config for a class library

I've been doing it the "right" way for a while and that has left me with lots of web.config and test project config files with info duplicated from class lib app.config files. I really do think that there is a specific, justified use case for doing this.

Thanks!

Was it helpful?

Solution

The best practice that I know of is to avoid direct dependency on app.config/web.config from classes in your library, or maybe even classes in general. That doesn't mean that you don't use app.config. It means that your classes don't know they're using it.

For example,

public class MyClassThatDependsOnSomeSettings
{
    private readonly ISettings _settings;

    public MyClassThatDependsOnSomeSettings(ISettings settings)
    {
        _settings = settings;
    }

    public void DoSomething()
    {
        var settingA = _settings.SettingA;
    }
}

public interface ISettings
{
    int SettingA {get;}
    string SettingB {get;}
}

Now you can consider MyClassThatDependsOnSomeSettings done. It doesn't require any access to a .config file. It just requires an instance of something that implements ISettings. That can read from .config.

public class SettingsFromConfiguration : ISettings 
{
    public int SettingA 
    {
        get 
        {
            string setting = ConfigurationManager.AppSettings["settingA"];
            int value = 0;
            int.TryParse(setting, out value);
            return value;
        }
    }

    public string SettingB 
    {
        get { return ConfigurationManager.AppSettings["settingB"];}
    }
}

Does it look like this just moves things around and does the same thing anyway? It does, almost. The big difference is that while you can use an implementation of ISettings that reads from app.config, you can also write other implementations. You can write one that uses hard-coded values, you could write a custom configuration section instead of using AppSettings, or if down the road you have an application with a JSON configuration file and no AppSettings your class can still work.

This applies the Dependency Inversion, which beneath everything means that classes should depend on abstractions (like interfaces) not concrete implementations.

Putting a requirement for ISettings in the constructor is called Dependency Injection, specifically constructor injection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top