我在 ASP.NET 核心上浏览了 configuration documentation。文档说您可以从应用程序中的任何位置访问配置。
下面是模板创建的 Startup.cs
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsEnvironment("Development"))
{
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
app.UseMvc();
}
}
所以在 Startup.cs
我们配置了所有的设置,Startup.cs 还有一个名为 Configuration
的属性
我无法理解您如何在控制器或应用程序的任何位置访问此配置? MS 建议使用 options pattern 但我只有 4-5 个键值对,所以我不想使用选项模式。我只是想访问应用程序中的配置。我如何在任何课程中注入它?
更新
使用 ASP.NET Core 2.0 将automatically将应用程序的 IConfiguration
实例添加到依赖项注入容器中。这也适用于 WebHostBuilder
上的 ConfigureAppConfiguration
。
例如:
public static void Main(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder =>
{
builder.AddIniFile("foo.ini");
})
.UseStartup<Startup>()
.Build();
host.Run();
}
就像在 ConfigureServices
中将 IConfiguration
实例作为单例对象添加到服务集合一样简单:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);
// ...
}
其中 Configuration
是您的 Startup
类中的实例。
这允许您在任何控制器或服务中注入 IConfiguration
:
public class HomeController
{
public HomeController(IConfiguration configuration)
{
// Use IConfiguration instance
}
}
正确的做法:
在 .NET Core 中,您可以将 IConfiguration
作为参数注入到 Class 构造函数中,它将可用。
public class MyClass
{
private IConfiguration configuration;
public MyClass(IConfiguration configuration)
{
ConnectionString = new configuration.GetValue<string>("ConnectionString");
}
现在,当您想要创建您的类的实例时,由于您的类被注入了 IConfiguration
,您将无法只执行 new MyClass()
,因为它需要将 IConfiguration
参数注入到构造函数中,所以,您还需要将您的类注入到注入链中,这意味着两个简单的步骤:
1) 在 Startup.cs
中的 ConfigureServices()
方法中将您的 Class/es - 您要使用 IConfiguration
的位置添加到 IServiceCollection
services.AddTransient<MyClass>();
2) 定义一个实例 - 假设在 Controller
中,并使用构造函数注入它:
public class MyController : ControllerBase
{
private MyClass _myClass;
public MyController(MyClass myClass)
{
_myClass = myClass;
}
现在您应该可以自由地享受您的 _myClass.configuration
...
另外的选择:
如果您仍在寻找一种无需将类注入控制器即可使其可用的方法,则可以将其存储在 static class
中,您将在 Startup.cs
中对其进行配置,例如:
public static class MyAppData
{
public static IConfiguration Configuration;
}
您的 Startup
构造函数应如下所示:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
MyAppData.Configuration = configuration;
}
然后在程序中的任意位置使用 MyAppData.Configuration
。
不要问我为什么第一个选项是正确的方法,我可以看到有经验的开发人员总是在他们的过程中避免垃圾数据,而且众所周知,始终在内存中提供大量数据并不是最佳实践,它对性能和开发都没有好处,也许只拥有你需要的东西也更安全。
System.Configuration
的原因。现在,您可以像过去一样访问您的旧 app.configs。我不是在这里谈论控制器。我们正在谈论具有自己配置的组件
我知道这很旧,但鉴于 IOptions 模式实现起来相对简单:
具有与配置中的设置匹配的公共 get/set 属性的类 public class ApplicationSettings { public string UrlBasePath { get;放; } } 注册您的设置 public void ConfigureServices(IServiceCollection services) { ... services.Configure
我不知道你为什么不这样做。
Microsoft.Extensions.Configuration
、Microsoft.Extensions.Configuration.Binder
和 Microsoft.Extensions.Configuration.Json
,然后加载 appsettings.json
文件,如 var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
..您还必须确保将 appsettings.json
复制到输出目录设置为copy always
还有一个选项可以在 startup.cs 中将 configuration
设为静态,以便您可以在任何地方轻松访问它,静态变量很方便哈!
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
internal static IConfiguration Configuration { get; private set; }
这使得使用 Startup.Configuration.GetSection...
可以在任何地方访问配置会出现什么问题?
我现在正在这样做:
// Requires NuGet package Microsoft.Extensions.Configuration.Json
using Microsoft.Extensions.Configuration;
using System.IO;
namespace ImagesToMssql.AppsettingsJson
{
public static class AppSettingsJson
{
public static IConfigurationRoot GetAppSettings()
{
string applicationExeDirectory = ApplicationExeDirectory();
var builder = new ConfigurationBuilder()
.SetBasePath(applicationExeDirectory)
.AddJsonFile("appsettings.json");
return builder.Build();
}
private static string ApplicationExeDirectory()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
var appRoot = Path.GetDirectoryName(location);
return appRoot;
}
}
}
然后我在需要从 appsettings.json 文件中获取数据的地方使用它:
var appSettingsJson = AppSettingsJson.GetAppSettings();
// appSettingsJson["keyName"]
appsettings.Development.json
自动覆盖 appsettings.json 中的值的可能性?
我知道可能有几种方法可以做到这一点,我正在使用 Core 3.1 并且正在寻找最佳/更清洁的选项,我最终这样做了:
我的启动类是默认的
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
我的 appsettings.json 是这样的
{
"CompanySettings": {
"name": "Fake Co"
}
}
我的类是一个 API 控制器,所以我首先添加了 using 引用,然后注入了 IConfiguration 接口
using Microsoft.Extensions.Configuration;
public class EmployeeController
{
private IConfiguration _configuration;
public EmployeeController(IConfiguration configuration)
{
_configuration = configuration;
}
}
最后我使用了 GetValue 方法
public async Task<IActionResult> Post([FromBody] EmployeeModel form)
{
var companyName = configuration.GetValue<string>("CompanySettings:name");
// companyName = "Fake Co"
}
我查看了选项模式示例并看到了这个:
public class Startup
{
public Startup(IConfiguration config)
{
// Configuration from appsettings.json has already been loaded by
// CreateDefaultBuilder on WebHost in Program.cs. Use DI to load
// the configuration into the Configuration property.
Configuration = config;
}
...
}
在我的类的构造函数中添加 Iconfiguration 时,我可以通过 DI 访问配置选项。
例子:
public class MyClass{
private Iconfiguration _config;
public MyClass(Iconfiguration config){
_config = config;
}
... // access _config["myAppSetting"] anywhere in this class
}
在 8-2017 年,Microsoft 推出了用于 .NET CORE v4.4 的 System.Configuration
。 Currently v4.5 和 v4.6 预览版。
对于我们这些致力于从 .Net Framework 到 CORE 的转换的人来说,这是必不可少的。它允许保留和使用当前的 app.config
文件,可以从任何程序集中访问这些文件。它甚至可能是 appsettings.json
的替代品,因为 Microsoft 意识到需要它。它与以前在 FW 中的工作方式相同。有一个区别:
在 Web 应用程序中,[例如 ASP.NET CORE WEB API] 您需要为您的 appSettings
或 configurationSection
使用 app.config
和 not web.config。您可能需要使用 web.config
,但前提是您通过 IIS 部署站点。您将 IIS 特定设置放入 web.config
我已经使用 netstandard20 DLL 和 Asp.net Core Web Api 对其进行了测试,并且一切正常。
使用 Options pattern in ASP.NET Core 是可行的方法。我只想补充一点,如果您需要访问您的 startup.cs 中的选项,我建议您这样做:
CosmosDbOptions.cs:
public class CosmosDbOptions
{
public string ConnectionString { get; set; }
}
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
// This is how you can access the Connection String:
var connectionString = Configuration.GetSection(nameof(CosmosDbOptions))[nameof(CosmosDbOptions.ConnectionString)];
}
我必须通过启动读取自己的参数。这必须在 WebHost 启动之前存在(因为我需要参数文件中的“监听”url/IP 和端口并将其应用于 WebHost)。此外,我需要在整个应用程序中公开设置。
在搜索了一段时间(没有找到完整的例子,只有片段)和各种尝试和错误之后,我决定用自己的 .ini 文件用“旧方式”来做。所以..如果你想使用你的拥有 .ini 文件和/或设置您自己的“监听 url/IP”和/或需要公开设置,这是给你的......
完整示例,适用于核心 2.1 (mvc):
创建一个 .ini 文件 - 示例:
[启动] URL=http://172.16.1.201:22222 [参数] *Dummy1=gew7623 Dummy1=true Dummy2=1
其中 Dummyx 仅作为字符串以外的其他日期类型的示例(并且还用于测试“错误参数”的情况(参见下面的代码)。
在项目的根目录中添加了一个代码文件,用于存储全局变量:
namespace MatrixGuide
{
public static class GV
{
// In this class all gobals are defined
static string _cURL;
public static string cURL // URL (IP + Port) on that the application has to listen
{
get { return _cURL; }
set { _cURL = value; }
}
static bool _bdummy1;
public static bool bdummy1 //
{
get { return _bdummy1; }
set { _bdummy1 = value; }
}
static int _idummy1;
public static int idummy1 //
{
get { return _idummy1; }
set { _idummy1 = value; }
}
static bool _bFehler_Ini;
public static bool bFehler_Ini //
{
get { return _bFehler_Ini; }
set { _bFehler_Ini = value; }
}
// add further GV variables here..
}
// Add further classes here...
}
更改了 program.cs 中的代码(在 CreateWebHostBuilder() 之前):
namespace MatrixGuide
{
public class Program
{
public static void Main(string[] args)
{
// Read .ini file and overtake the contend in globale
// Do it in an try-catch to be able to react to errors
GV.bFehler_Ini = false;
try
{
var iniconfig = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddIniFile("matrixGuide.ini", optional: false, reloadOnChange: true)
.Build();
string cURL = iniconfig.GetValue<string>("Startup:URL");
bool bdummy1 = iniconfig.GetValue<bool>("Parameter:Dummy1");
int idummy2 = iniconfig.GetValue<int>("Parameter:Dummy2");
//
GV.cURL = cURL;
GV.bdummy1 = bdummy1;
GV.idummy1 = idummy2;
}
catch (Exception e)
{
GV.bFehler_Ini = true;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("!! Fehler beim Lesen von MatrixGuide.ini !!");
Console.WriteLine("Message:" + e.Message);
if (!(e.InnerException != null))
{
Console.WriteLine("InnerException: " + e.InnerException.ToString());
}
Console.ForegroundColor = ConsoleColor.White;
}
// End .ini file processing
//
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>() //;
.UseUrls(GV.cURL, "http://localhost:5000"); // set the to use URL from .ini -> no impact to IISExpress
}
}
这边走:
我的应用程序配置与 appsettings.json 分离,如果 MS 在未来版本中发生更改,我无需担心任何副作用;-)
我在全局变量中有我的设置
我可以为每个设备设置“监听 url”,应用程序运行(我的开发机器、内网服务器和互联网服务器)
我能够以旧方式停用设置(只需在之前设置一个 *)
如果 .ini 文件有问题(例如类型不匹配),我能够做出反应 如果 - 例如 - 设置了错误的类型(例如,*Dummy1=gew7623 被激活而不是 Dummy1=true)主机显示红色控制台上的信息(包括异常),我也能够在应用程序中做出反应(GV.bFehler_Ini 设置为 true,如果 .ini 有错误)
不定期副业成功案例分享
IConfiguration
非常容易泄漏。使用 Options pattern 要好得多。