In .net 6, how do I pass the parameter to the constructor when the service initialization comes before the configuration binding of values?

I can’t seem to find the solution to my exact problem, because I need to call the dependency injection before calling the builder, but this results in a new object instantiation in the controller class and the values are lost.
If I put this line right after binding, I can get an error saying cannot modify the service after it has been built.

In the older version of .net, since Startup.cs is existing, this doesn’t seem to be a problem due to the separation of methods ConfigureService and Configure.

AuthenticationBind.cs

public class AuthenticationBind
{
    public int AuthenticationId { get; set; }
    public string AuthenticationName { get; set; }
}

appsettings.json

 {
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "TestAuthenticationBind": {
    "AuthenticationId": "1324556666",
    "AuthenticationName": "Test Authentication Name"
  },
  "AllowedHosts": "*"
}

Program.cs

    var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

builder.Services.AddSingleton<AuthenticationBind>();

var app = builder.Build();

AuthenticationBind tb = new AuthenticationBind();
IConfiguration configuration = app.Configuration;
configuration.Bind("TestAuthenticationBind", tb);

AuthenticationController.cs

    private readonly AuthenticationBind authenticationBind;
    public AuthenticationController(AuthenticationBind authenticationBind)
    {
        this.authenticationBind = authenticationBind;
    }

Also, can I use the object instance to pass to services.AddSingleton method, instead of the class itself, like below?

builder.Services.AddSingleton<tb>();

>Solution :

It appears you’re trying to bind configuration values into models. You can do this by calling IServiceCollection.Configure<T>() – for your code, it would look like this:

builder.Services.Configure<AuthenticationBind>(builder.Configuration.GetSection("TestAuthenticationBind"));

Afterwards, you can use the IOptions<T> interface in your controller to access the (bound) object:

public AuthenticationController(
  IOptions<AuthenticationBind> authOptions
)
{
  // You can access authOptions.Value here
}

Same goes in the startup class, you can request the IOptions interface like so:

var authOptions = app.Services.GetRequiredService<IOptions<AuthenticationBind>>();

Leave a Reply