IMO 类库应该与应用程序设置数据无关。一般来说,图书馆消费者是关心这些细节的人。是的,这并不总是正确的(例如,如果您有一个进行 RSA 加密/解密的类,您可能需要一些私有配置以允许私钥生成/存储),但在大多数情况下,这是正确的。
因此,一般来说,尽量将应用程序设置排除在类库之外,并让消费者提供此类数据。在您的评论中,您提到了数据库的连接字符串。这是将数据保留在类库之外的完美示例。图书馆不应该关心它调用什么数据库来读取,只是它需要从一个数据库中读取。下面的例子(如果有一些错误,我很抱歉,因为我是从记忆中写出来的):
图书馆
使用连接字符串的库类
public class LibraryClassThatNeedsConnectionString
{
private string connectionString;
public LibraryClassThatNeedsConnectionString(string connectionString)
{
this.connectionString = connectionString;
}
public string ReadTheDatabase(int somePrimaryKeyIdToRead)
{
var result = string.Empty;
// Read your database and set result
return result;
}
}
应用程序
appsettings.json
{
"DatabaseSettings": {
"ConnectionString": "MySuperCoolConnectionStringWouldGoHere"
}
}
数据库设置.cs
public class DatabaseSettings
{
public string ConnectionString { get; set; }
}
Startup.cs
public class Startup
{
public Startup(IHostingEnvironment env)
{
Configuration = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables()
.Build();
}
public IConfigurationRoot Configuration { get; }
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Setup logging
// Configure app
}
public void ConfigureServices(IServiceCollection services)
{
// Configure services
services.Configure<DatabaseSettings>(Configuration.GetSection("DatabaseSettings"));
services.AddOptions();
// Register our class that reads the DB into the DI framework
services.AddTransient<IInterfaceForClass, ClassThatNeedsToReadDatabaseUsingLibrary>();
}
}
使用库类读取数据库的类
public interface IInterfaceForClass
{
string ReadDatabaseUsingClassLibrary(int somePrimaryKeyIdToRead);
}
public class ClassThatNeedsToReadDatabaseUsingLibrary : IInterfaceForClass
{
private DatabaseSettings dbSettings;
private LibraryClassThatNeedsConnectionString libraryClassThatNeedsConnectionString;
public ClassThatNeedsToReadDatabaseUsingLibrary(IOptions<DatabaseSettings> dbOptions)
{
this.dbSettings = dbOptions.Value;
this.libraryClassThatNeedsConnectionString = new LibraryClassThatNeedsConnectionString(this.dbSettings.ConnectionString);
}
public string ReadDatabaseUsingClassLibrary(int somePrimaryKeyIdToRead)
{
return this.libraryClassThatNeedsConnectionString.ReadTheDatabase(somePrimaryKeyIdToRead);
}
}
一些处理从数据库读取的 UI 内容的控制器类
public class SomeController : Controller
{
private readonly classThatReadsFromDb;
public SomeController(IInterfaceForClass classThatReadsFromDb)
{
this.classThatReadsFromDb = classThatReadsFromDb;
}
// Controller methods
}
TL;DR
尽量避免在类库中使用应用程序设置。相反,让您的类库对此类设置不可知,并让消费者传递这些设置。
编辑:
我将依赖注入添加到控制器类中,以演示使用依赖注入来构建从数据库读取的类。这让 DI 系统可以解决必要的依赖关系(例如 DB 选项)。
这是一种方法(也是最好的方法)。另一种方法是将 IOptions 注入控制器并手动更新从数据库读取的类并将选项传入(不是最佳实践,DI 是更好的方法)