[英]Calling appsettings.json data from another class in a console app
以下是Microsoft 文档中的示例代码,它显示了如何在控制台应用程序中使用 appsettings.json :
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace ConsoleJson.Example
{
class Program
{
static async Task Main(string[] args)
{
using IHost host = CreateHostBuilder(args).Build();
// Application code should start here.
await host.RunAsync();
}
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, configuration) =>
{
configuration.Sources.Clear();
IHostEnvironment env = hostingContext.HostingEnvironment;
configuration
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
IConfigurationRoot configurationRoot = configuration.Build();
TransientFaultHandlingOptions options = new();
configurationRoot.GetSection(nameof(TransientFaultHandlingOptions))
.Bind(options);
Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");
});
}
}
我需要在另一个 class的方法中获取配置值,如下所示。 我想我需要使用依赖注入并将IConfigurationRoot
发送到myClass
, 如此链接所示,但无法弄清楚到底如何?
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace ConsoleJson.Example
{
class Program
{
static void Main(string[] args)
{
using IHost host = CreateHostBuilder(args).Build();
IDatabase db = xyz.GetDatabase();
ConfigureServices.Initialize(db);
}
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, configuration) =>
{
configuration.Sources.Clear();
IHostEnvironment env = hostingContext.HostingEnvironment;
configuration
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
IConfigurationRoot configurationRoot = configuration.Build();
TransientFaultHandlingOptions options = new();
configurationRoot.GetSection(nameof(TransientFaultHandlingOptions))
.Bind(options);
});
}
class ConfigureServices
{ public static void Initialize(IDatabase db)
{
Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");
}
}
}
所以,我需要从appsettings.json
获取值并在我的 Initialize 方法中使用它们。 我可以通过对值进行硬编码来使用代码的 rest。
我尝试在 ConfigureAppConfiguration 之后添加以下行,但它无法识别configurationRoot
.ConfigureServices((_, services) =>services.AddSingleton<IConfigurationRoot>(configurationRoot));
真诚感谢所有帮助。 谢谢
您可以尝试将 IOptions 模式从 .NET 核心注入到您的 class 中。
执行以下操作:
假设你的 appSettings.json 如下图所示:
"AppSettings": {
"AppValue": "1"
}
创建一个 class 来保存您的配置值:
public class AppConfiguration
{
public AppConfiguration() { }
public string AppValue { get; set; }
}
在您的 Startup.cs 中,将配置 class 添加到服务集合中,如下所示:
using Microsoft.Extensions.Configuration;
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppConfiguration>(Configuration.GetSection("AppSettings"));
…
}
在您的 class 中,将 IOptions 注入 class。 为配置分配一个内部变量。 参考 class 中的配置数据并获取设置属性:
using Microsoft.Extensions.Options;
…
public class MyService: IMyService
{
private readonly IOptions<AppConfiguration> _appConfiguration;
public MyService(..., IOptions<AppConfiguration> appConfiguration, …)
{
...
_appConfiguration = appConfiguration;
}
public SomeTask()
{
// Do something with _appConfiguration.Value.AppValue;
}
}
这将允许您的自定义类从您的 appSettings.json 获取值。
此外,对于您的应用程序构建器,建议您的应用程序管道使用启动 class,如下所示:
Host.CreateDefaultBuilder(args)
.UseStartup<Startup>();
那么你的 Startup class 应该有以下方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
}
public void ConfigureServices(IServiceCollection services)
{
}
当你创建一个新的 .NET Core Web App 时,可以重新生成一个类似的骨架启动 class。 试试上面的,让我知道它是怎么回事。
这里的一切都可以通过在控制台中适当地配置主机来完成。
由于没有提供您正在尝试做的事情的正确表示,我将不得不根据您的示例中实际提供的内容做出一些假设。
首先将您的类重构为实例并尽量避免 static 耦合,以便可以正确使用依赖注入
public class ConfigureServices {
private readonly TransientFaultHandlingOptions options;
private readonly IDatabase db;
public ConfigureServices(TransientFaultHandlingOptions options, IDatabase db) {
this.options = options;
this.db = db;
}
public void Initialize() {
Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");
//... access db and options as needed here
}
}
查看以下评论以了解主机的构建方式。
class Program {
static void Main(string[] args) {
using IHost host = CreateHostBuilder(args).Build();
ConfigureServices config = host.Services.GetRequiredService<ConfigureServices>();
config.Initialize();
host.Run();
}
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, configuration) => {
configuration.Sources.Clear();
IHostEnvironment env = hostingContext.HostingEnvironment;
configuration
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
//After this delegate has been invoked, the configuration
//will be built and added to the HostBuilderContext
})
.ConfigureServices((hostingContext, services) => {
//Get built configuration from the host builder context
IConfiguration configuration = hostingContext.Configuration;
//Extract the options from configuration.
TransientFaultHandlingOptions options = configuration
.GetSection(nameof(TransientFaultHandlingOptions))
.Get<TransientFaultHandlingOptions>();
//And add it to services so it can be injected as needed
services.AddSingleton<TransientFaultHandlingOptions>(_ => options);
//Add IDatabase so it to can be injected and resolved as needed.
services.AddScoped<IDatabase>(_ => xyz.GetDatabase());
});
}
将所有必要的依赖项添加到主机后,如上所示解析所需的服务
//...
ConfigureServices config = host.Services.GetRequiredService<ConfigureServices>();
config.Initialize();
//...
真的没有必要手动传递参数。
甚至手动调用ConfigureServices.Initialize()
也可能被注入到IHostedService
中,并且会在主机启动时为您调用它。
public class DatabaseInitializeService: BackgroundService {
private readonly ConfigureServices config;
public DatabaseInitializeService(ConfigureServices config) {
this.config = config;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken) {
config.Initialize();
return Task.CompletedTask;
}
}
托管服务将添加到ConfigureServices
扩展中
//...
services.AddHostedService<DatabaseInitializeService>();
//...
和以前一样简化了Main
方法。
static void Main(string[] args) {
using IHost host = CreateHostBuilder(args).Build();
host.Run();
}
我有类似的情况。 我想将 AppSettings.Json 自定义密钥访问到我的 asp.net 核心 mvc 项目的 controller 中。 我正在分享可能对您有帮助的控制台应用程序示例代码。
我使用了标准的 VS 2019 控制台应用程序模板和 asp.net 核心,目标为 .net 5.0。
我的项目文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.6" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.MSSqlServer" Version="5.6.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
我的 AppSettings.Json 是:
{
"AppSettings": {
"FTPLocation": "\\\\FTPHostname\\\\c$\\\\Folder\\\\ftpSite\\\\Prod\\",
"FTPUri": "ftp://ftphostname/myFolder/",
"CSVFileName": "TestData.csv",
},
"ConnectionStrings": {
"AppDbConnString": "Server=sqlserverhost.domain.com;Database=DBName; Trusted_Connection=True; MultipleActiveResultSets=true"
,
"IdentityConnection": "Server=hostname.domain.com;Database=IdentityDBName; Trusted_Connection=True; MultipleActiveResultSets=true"
},
"EmailAddresses": [
"email1@test.com",
"email2@test.com",
"email3@test.com"
],
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
我的 Program.cs 是:
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Microsoft.Extensions.Logging;
using System.IO;
namespace AppSettingsExample
{
class Program
{
public static IConfigurationRoot configuration;
static void Main(string[] args)
{
ServiceCollection serviceDescriptors = new ServiceCollection();
ConfigureServices(serviceDescriptors);
Serilog.Log.Information("Building service provider");
IServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
Console.WriteLine(configuration.GetConnectionString("AppDbConnString"));
try
{
Serilog.Log.Information("start service provider");
_ = serviceProvider.GetService<App>().Run();
Serilog.Log.Information("end service provider");
}
catch (Exception ex)
{
Serilog.Log.Fatal(ex, "Error in building service ");
throw;
}
finally
{
Serilog.Log.CloseAndFlush();
}
var connectionString = configuration.GetSection("ConnectionStrings:AppDbConnString").Value;
Console.WriteLine(connectionString);
var securityGroups = configuration.GetSection("ADSecurityGroups:SupervisorSecurityGroups").Value.Split(';');
foreach (var securityGroup in securityGroups)
{
Console.WriteLine(securityGroup);
}
}
private static void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton(LoggerFactory.Create(builder =>
{
builder.AddSerilog(dispose: true);
}));
serviceCollection.AddLogging();
configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("appsettings.json")
.Build();
serviceCollection.AddSingleton<IConfigurationRoot>(configuration);
serviceCollection.AddTransient<App>();
}
}
}
我的 App.cs 是:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppSettingsExample
{
public class App
{
private readonly IConfigurationRoot _config;
private readonly ILogger<App> _logger;
public App(IConfigurationRoot config, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<App>();
_config = config;
}
public async Task Run()
{
List<string> emailAddresses = _config.GetSection("EmailAddresses").Get<List<string>>();
foreach (string emailAddress in emailAddresses)
{
Console.WriteLine(emailAddress);
}
}
}
}
此控制台应用程序的 Output:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.