简体   繁体   中英

How can other developer know that class library is using app.config? Or should I just eliminate app.config?

Just as an example, I created a class library (Email.DLL) that sends an email. In order to send an email, SmtpClient needs credentials, which are currently being read from app.config.

So now I created a separate console app (SendStuff.exe) that sends an email, so I added Email.dll as reference. Being the one that created both the DLL and the console app, I know that I need to add the appropriate keys in the console app's appSettings of app.config in order for the email to be sent.

Now, let's say that someone else uses the DLL. How would he know that his application needs to include the appropriate appSettings so that my Email.DLL can send the email?

Or would it be better to just eliminate app.config from the class library and find some other way to set the credentials?

Using the local config file is a perfectly standard approach. Usually, you would include this information in the documentation that accompanies the library. Often, there's a Getting Started or Tutorial page.

With that said, I'd also implement clear and actionable exceptions that are thrown when these configuration values are missing. Something like:

Could not find SMTP credentials in App.config. See documentation for more information.

Lastly, if you distribute your library with something like NuGet , you can automatically include default configurations that will be set when the library is added through the package manager.

I can think of two high-level approaches, depending on the answer to one question...

  • Does this library abstract its implementation details from the consuming code?

If "yes", then I would provide with the library a sample app.config to demonstrate how to configure it. When the library loads, it can check for configuration values and throw an exception if they're not available. This could be useful in the case of, for example, a generic messaging interface where consuming code doesn't need to know if it's email:

public class Messenger : IMessenger
{
    public Messenger()
    {
        // maybe confirm config values here
    }

    public void Send(string message, User recipient)
    {
        // implementation details
    }
}

Make the exception very explicit so it's obvious what the problem is.

If, on the other hand, the answer is "no" and the "SMTP-ness" of the library doesn't need to be behind a more abstract interface, then the library can just as easily require the configuration when you use it:

public class Messenger
{
    public Messenger(string smtpServer, int port)
    {
        // set the local class values from the supplied values
    }

    public void Send(string message, string recipientEmail)
    {
        // implementation details
    }
}

This de-couples the library from the configuration details entirely and forces the consuming code to supply those values. For the developer using the library, this is much more obvious. It does, however, require that the implementation details be statically exposed by the code so it's less abstraction. Pros and cons either way.

To my mind it is better to not read the credentials from within your library at all. Let the caller pass the credential to smtp client.

eg:

SmtpClient client = new SmptClient(string username, string password);

This makes it obvious to the consumer what he needs to do so that he can use the class. The consumer can still decide to store the username/password in the app.config or pull the credentials from somewhere else (eg a database).

I agree that using the app.config is not uncommon but I would only suggest it if the data can't be easily passed to the component from within code.

Even if the data structure is complicated (eg configuring a logger) you still should give the consumer the possibility to use your component purely from code. So eg log4net is usually configured with a config file however you can always use the Configure() method to get around it.

log4net.Config.XmlConfigurator.Configure(XmlElement element)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM