15

This appears to be a similar problem but none of the answers are fitting for my code...: Read appsettings.json in Main Program.cs

This is extremely similar but does not work for me for some reason: ASP.NET Core 6 how to access Configuration during setup

I'm porting a .NET 6 beta application to stable version of .NET 6.

This means I want to port the code responsible for importing IConfiguration (yes I'm aware it's backwards compatible with the separate Startup.cs and Program.cs files, but I'm willing to use the new syntax). IConfiguration is basically the file appsettings.json in ASP.NET Core.

In old code it looks like this:

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

I tried the following:

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

It seems that the Microsoft.Extensions.Configuration isn't even used! The syntax I got is from this blog post: https://gavilan.blog/2021/08/19/getting-the-iconfiguration-in-the-program-class-asp-net-core-6/

This problem is primitive, but I don't seem to get it right. Any help is appreciated to solve this problem being that it works in new .NET 6 minimal API.

I found this guide useful but it apparently didn't solve the problem at hand: https://www.mikesdotnetting.com/article/357/razor-pages-startup-in-net-6

In another Model I have this code which is also not valid anymore:

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

I tried replacing Startup with Program but it didn't seem to work...

The errors I'm getting are:

'Program' does not contain a definition for 'Configuration'
Munchkin
  • 857
  • 5
  • 24
  • 51
  • Just to clarify you are getting a compile time error and no runtime error? Your error `'Program' does not contain a definition for 'Configuration'` sounds like a syntax error, could you share the whole file? – Rand Random Jan 26 '22 at 15:12
  • @RandRandom to clarify: the error appears with the already provided code, in which I replaced `Startup` with `Program` – Munchkin Jan 26 '22 at 15:13

2 Answers2

24
  1. Switching to minimal hosting model is not required, you can still use the generic hosting (the one with startup).

It seems that the Microsoft.Extensions.Configuration isn't even used!

The using Microsoft.Extensions.Configuration; directive is not needed cause new feature global using statements is heavily utilized in .NET 6 templates.

3.

var Configuration = builder.Configuration;

The Program file in the new templates is using another relatively new feature (C# 9) - top-level statements, so the var Configuration is just a variable accessible only inside the generated Main method.

4.

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

You can access this value inside the top-level statement file via:

var secret = builder.Configuration["GoogleRecaptchaV3:Secret"];

To make settings accessible outside that file (or Startup in generic hosting) I highly recommend to use DI (as shown in the docs here or here).

In case if you have A LOT of code relying on static configuration being available and you need a quick temporary fix you can add partial Program class at the end of the top-level statement file and do something like:

// ....
WebApplication app = builder.Build();
Configuration = app.Configuration;
// ...

public partial class Program
{
    internal static IConfiguration Configuration  { get; private set; }
}

But I highly recommend against that.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    Great answer, but I would really appreciate if you could add the recommended way (using Dependency Injection). I can't seem to figure it out, I'm apparently still a beginner with C#. Much appreciated! – Munchkin Jan 27 '22 at 11:57
  • 1
    @Munchkin it is covered in linked to point 4 articles. Basically you parse (or bind) configuration during the app build phase and register it in DI (with call like `builder.Services.Configure`) and then resolve it in class which needs it by adding constructor parameter of that type (i.e. `public SomeService(YourConfigName cfg....)`), and the class should be registered and resolved also. – Guru Stron Jan 27 '22 at 13:08
  • @Munchkin Check out [this](https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection) and [this](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0) articles about DI and try following along – Guru Stron Jan 27 '22 at 13:09
  • 1
    Seems I got it to work with the following code (it's your not recommended approach with a little modification): `Configuration = app.Configuration; // ... public partial class Program { internal static IConfiguration Configuration { get; private set; } }` – Munchkin Jan 27 '22 at 15:11
  • 1
    Nooope, that code I provided above does not allow reading from the config, don't use it, it only allows the app to run unlike the temporary solution you provided at the end, but as I've already mentioned it's not functional... – Munchkin Jan 28 '22 at 12:01
3

The following works as a basic and direct implementation:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var config = app.Configuration;

Edited following Guru Stron's comment.

Finn
  • 51
  • 3