在C#类库中使用IConfiguration
我正在使用C#和Core .NET构建一个类库。 我试图使用config.json
文件中的配置。 以下是该文件的内容:
config.json
{ "emailAddress":"someone@somewhere.com" }
在尝试使用config.json
进行配置时,我在我的project.json
文件中引用了Microsoft.Framework.ConfigurationModel.Json
。 在我的代码中,我有以下内容:
MyClass.cs
using Microsoft.Framework.ConfigurationModel; public class MyClass { public string GetEmailAddress() { // return ConfigurationManager.AppSettings["emailAddress"]; This is the approach I had been using since .NET 2.0 return ?; // What goes here? } }
从.NET 2.0开始,我一直在使用ConfigurationManager.AppSettings["emailAddress"]
。 但是,我现在正试图通过IConfiguration
学习如何以新方式实现这一目标。 我的问题是,这是一个类库。 出于这个原因,我不确定配置文件的加载方式,地点或时间。 在传统的.NET中,我只需要为ASP.NET项目命名文件web.config,为其他项目命名app.config。 现在,我不确定。 我有一个ASP.NET MVC 6项目和一个XUnit项目。 所以,我试图弄清楚如何在这两种场景中使用config.json
。
谢谢!
从未使用它,但快速搜索引导我这…
var configuration = new Configuration(); configuration.AddJsonFile(“config.json”); var emailAddress = configuration.Get("emailAddress");
也许你可以试试。
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" } }
DatabaseSettings.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(Configuration.GetSection("DatabaseSettings")); services.AddOptions(); // Register our class that reads the DB into the DI framework services.AddTransient(); } }
使用库类读取数据库的类
public interface IInterfaceForClass { string ReadDatabaseUsingClassLibrary(int somePrimaryKeyIdToRead); } public class ClassThatNeedsToReadDatabaseUsingLibrary : IInterfaceForClass { private DatabaseSettings dbSettings; private LibraryClassThatNeedsConnectionString libraryClassThatNeedsConnectionString; public ClassThatNeedsToReadDatabaseUsingLibrary(IOptions 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
尽量避免在类库中使用应用程序设置。 相反,让您的类库与这些设置无关,并让消费者传递这些设置。
编辑:
我在dependency injection中添加了一个控制器类来演示使用dependency injection来构建从DB读取的类。 这使DI系统解决了必要的依赖关系(例如DB选项)。
这是做到这一点的一种方式(也是最好的方式)。 另一种方法是将IOptions注入控制器并手动新建从DB读取并传递选项的类(不是最佳实践,DI是更好的方法)
首先在.csproj
文件中添加一个在构建过程中hocks的目标,如果以下内容不符合您的需求,请参阅更多选项的链接,例如发布
你可以像下面这样使用它
using Microsoft.Framework.ConfigurationModel; using Microsoft.Extensions.Configuration; using System; public class MyClass { public string GetEmailAddress() { //For example purpose only, try to move this to a right place like configuration manager class string basePath= System.AppContext.BaseDirectory; IConfigurationRoot configuration= new ConfigurationBuilder() .SetBasePath(basePath) .AddJsonFile("config.json") .Build(); return configuration.Get("emailAddress"); } }
不知道它是否在core.net库中工作,但在我的mvc6应用程序中,我用这种方式:
public class Startup { public static IConfigurationRoot Configuration; public Startup(IApplicationEnvironment appEnv) { var builder = new ConfigurationBuilder() .SetBasePath(appEnv.ApplicationBasePath) .AddJsonFile("config.json") .AddEnvironmentVariables(); Configuration = builder.Build(); } }
那么如果我需要在整个应用程序中调用config.jason中的信息,我会这样做:即在控制器方法中:
var email = Startup.Configuration["AppSettings:SiteEmailAddress"];
我的WonderContext类中的sql字符串:
var connString = Startup.Configuration["AppSettings:WonderContextConnection"];
- 获取实现某个抽象类的所有类
- HTTP错误404.13 – asp.net核心2.0
- validationJWT令牌后访问dotnetcore中间件
- Docker在VS中运行但在发布到AWS时出错? 错误CS5001:程序不包含适用于入口点的静态“主”方法
- 在dotnet核心中读取json文件时出错“已达到inotify实例数量的已配置用户限制(128)”
- 在实体Framework Core中执行存储过程而不期望映射到dbset
- .NET Core中的SOAP?
- 如何运行.Net Core dll?
- .NET Core IServiceScopeFactory.CreateScope()vs IServiceProvider.CreateScope()扩展