I can think of two high-level approaches, depending on the answer to one question ...
- Does this library describe its implementation details from the consumption code?
If yes, then I would give the library a sample app.config to demonstrate how to configure it. When the library loads, it can check the configuration values and throw an exception if they are not available. This can be useful in the case of, for example, a universal messaging interface in which the consumer code does not need to know if it is sent by email:
public class Messenger : IMessenger { public Messenger() {
Make the exception very explicit so that it is obvious that the problem is.
If, on the other hand, the answer is “no,” and the “SMTP version” of the library does not need a more abstract interface, then the library can just as easily require configuration when you use it:
public class Messenger { public Messenger(string smtpServer, int port) {
This completely disconnects the library from the configuration details and forces the consumption code to provide these values. For a developer using a library, this is much more obvious. However, this requires implementation details to be exposed to static code to reduce abstraction. Pros and cons anyway.
David source share