0

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!

Community
  • 1
  • 1
Josh R
  • 1,970
  • 3
  • 27
  • 45
  • 1
    I don't think the duplication is in the application's config files. The duplication is in the class library's config files. Class libraries by themselves don't use config files, so I've never understood why Visual Studio creates them. I suppose they serve as sample configurations, but then they should be treated differently and not just be called `App.config`. Out of curiosity, if you *know* it's bad practice and you *know* it would "horribly twist a C# project" then why would you want to attempt it? – David Aug 02 '13 at 22:49
  • Have you tried setting the build option of a config (or what have you) to 'Embedded Resource' and then pull it out of the assembly using reflection? – Gayot Fow Aug 02 '13 at 23:08
  • Thanks for the comments; I think the better question to ask is: "How can I have a config file in a class library and get the calling application to read it?" and the reasoning behind this is I want a class library whose code is basically lots of web service or db calls with error handling, retry logic, logging, etc... to be able to be reused in many projects/solutions without having to add the config information to all of those projects (reducing duplication of code). I'm a jr dev so if I'm going about this completely wrong I'm very open to corrections and/or advice. @Gary will try that – Josh R Aug 03 '13 at 00:37

1 Answers1

1

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.

showdev
  • 28,454
  • 37
  • 55
  • 73
Scott Hannen
  • 27,588
  • 3
  • 45
  • 62