简体   繁体   English

其他开发人员如何知道类库正在使用app.config? 或者我应该消除app.config?

[英]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. 举个例子,我创建了一个发送电子邮件的类库(Email.DLL)。 In order to send an email, SmtpClient needs credentials, which are currently being read from app.config. 为了发送电子邮件, SmtpClient需要凭据,这些凭据当前正在从app.config中读取。

So now I created a separate console app (SendStuff.exe) that sends an email, so I added Email.dll as reference. 所以现在我创建了一个发送电子邮件的独立控制台应用程序(SendStuff.exe),所以我添加了Email.dll作为参考。 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. 作为创建DLL和控制台应用程序的人,我知道我需要在app.config的控制台应用程序appSettings中添加适当的密钥才能发送电子邮件。

Now, let's say that someone else uses the DLL. 现在,让我们说其他人使用DLL。 How would he know that his application needs to include the appropriate appSettings so that my Email.DLL can send the email? 他怎么知道他的应用程序需要包含适当的appSettings以便我的Email.DLL可以发送电子邮件?

Or would it be better to just eliminate app.config from the class library and find some other way to set the credentials? 或者,从类库中删除app.config并找到其他设置凭据的方法会更好吗?

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. 无法在App.config中找到SMTP凭据。 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. 最后,如果您使用NuGet之类的东西分发库,则可以自动包含在通过包管理器添加库时将设置的默认配置

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. 如果“是”,那么我将向库提供一个示例app.config来演示如何配置它。 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: 另一方面,如果答案是“否”并且库的“SMTP-ness”不需要在更抽象的界面后面,那么当您使用它时,库可以很容易地要求配置:

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. 让调用者将凭证传递给smtp客户端。

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). 消费者仍然可以决定将用户名/密码存储在app.config中,或者从其他地方(例如数据库)提取凭据。

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. 我同意使用app.config并不罕见但我只建议如果数据无法从代码中轻松传递给组件。

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通常配置有配置文件,但是您始终可以使用Configure()方法来解决它。

log4net.Config.XmlConfigurator.Configure(XmlElement element)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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