在Program.cs中设置.NET 6(稳定版)的IConfiguration配置

15

这似乎是一个类似的问题,但没有一个答案适用于我的代码...: 在Main Program.cs中读取appsettings.json

这非常相似,但出于某种原因对我不起作用: ASP.NET Core 6如何在设置期间访问配置

我正在将一个 .NET 6 beta 应用程序移植到 .NET 6 的稳定版本。

这意味着我想移植负责导入 IConfiguration 的代码(是的,我知道它与单独的 Startup.csProgram.cs 文件向后兼容,但我愿意使用新的语法)。IConfiguration 基本上是 ASP.NET Core 中的 appsettings.json 文件。

在旧代码中,它看起来像这样:

 public class Startup
    {
        internal static IConfiguration Configuration { get; private set; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

我尝试了以下方法:

using Microsoft.Extensions.Configuration;
// IConfiguration init test
var Configuration = builder.Configuration;

看起来 Microsoft.Extensions.Configuration 甚至没被使用!我得到的语法是从这篇博客文章中学来的:https://gavilan.blog/2021/08/19/getting-the-iconfiguration-in-the-program-class-asp-net-core-6/

这个问题很基础,但我好像做不对。希望能得到任何帮助以解决这个问题,因为它在新的 .NET 6 minimal API 上可以工作。

我发现这个指南很有用,但显然没有解决手头的问题:https://www.mikesdotnetting.com/article/357/razor-pages-startup-in-net-6

在另一个 Model 中,我有这段代码也不再有效:

secret = Startup.Configuration["GoogleRecaptchaV3:Secret"];
                path = Startup.Configuration["GoogleRecaptchaV3:ApiUrl"];

我尝试将“Startup”替换为“Program”,但似乎没有起作用...

我得到的错误是:

'Program' does not contain a definition for 'Configuration'

只是为了澄清,您得到的是编译时错误而不是运行时错误吗?您的错误 'Program' does not contain a definition for 'Configuration' 听起来像是语法错误,您可以分享整个文件吗? - Rand Random
@RandRandom 澄清一下:错误出现在已经提供的代码中,我将 Startup 替换为 Program - Munchkin
2个回答

26
  1. 切换到极简托管模型并非必需,您仍然可以使用通用托管(包含启动项)。

看起来 Microsoft.Extensions.Configuration 甚至没有被使用!

由于.NET 6模板中广泛使用了新功能全局 using 语句,所以不需要使用 using Microsoft.Extensions.Configuration; 指令。

3.

var Configuration = builder.Configuration;

新模板中的 Program 文件正在使用另一种相对较新的功能(C# 9)- 顶级语句,因此 var Configuration 只是一个仅在生成的 Main 方法内部可访问的变量。

4.

secret = Startup.Configuration["GoogleRecaptchaV3:Secret"];

您可以通过以下方式在顶级语句文件中访问此值:

var secret = builder.Configuration["GoogleRecaptchaV3:Secret"];
为了使设置在文件外部可访问(或 Startup 在通用托管中),我强烈建议使用DI(如文档所示这里这里)。

如果您有很多代码依赖于可以使用静态配置并且需要快速临时修复,您可以在顶级语句文件的末尾添加 partial Program 类,并执行以下操作:

<code>// ....
WebApplication app = builder.Build();
Configuration = app.Configuration;
// ...

public partial class Program
{
    internal static IConfiguration Configuration  { get; private set; }
}
</code>

但我强烈不建议那样做。


1
非常好的回答,但我真的很感激如果您能添加推荐的方式(使用依赖注入)。我似乎无法弄清楚,显然我还是C#的初学者。非常感谢! - Munchkin
1
@Munchkin,这个问题在链接的第4篇文章中有详细介绍。基本上,在应用程序构建阶段解析(或绑定)配置,并通过调用builder.Services.Configure<YourConfigName>将其注册到 DI 中,然后通过为需要它的类添加该类型的构造函数参数(例如 public SomeService(YourConfigName cfg....))来解决它,同时该类也应该被注册和解决。 - Guru Stron
@Munchkin 请查看关于 DI 的 这篇这篇 文章,并尝试跟随其中的内容。 - Guru Stron
1
看起来我用以下代码解决了问题(这是您不推荐的方法,稍作修改):`Configuration = app.Configuration; // ...public partial class Program { internal static IConfiguration Configuration { get; private set; } }` - Munchkin
1
不好意思,我提供的那段代码无法读取配置文件,请不要使用它。它只能让应用程序运行,而不能像你在最后提供的临时解决方案那样实现读取配置文件的功能。但正如我之前所提到的,那个临时解决方案也是不可行的。 - Munchkin

3
以下内容是基本而直接的实现方式:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var config = app.Configuration;

在Guru Stron的评论下进行了编辑。


为什么你需要在这里使用作用域?你可以直接使用 app.Configuration - Guru Stron
@GuruStron 同意,这个例子不需要范围。谢谢。 - Finn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接