Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection with Options pattern in .net 6

In console application with dependency injection with Options pattern I'm trying to load user input. How can I make "factory like" resolving of

IOptions<ArgSettings> 

to load input arguments. If required input arguments are not provided (null or not valid) then use default settings from appsettings.json?

    public class ArgSettings
    {
        public string Name { get; set; }
        public string Region { get; set; }
    }

    public interface IService
    {
        void DoSomthing();
    }


    public class MyService: IService
    {
        private readonly ArgSettings _argSettings;

        public MyService(IOptions<ArgSettings> cfg)
        {
            _argSettings = cfg.Value;

        }
        public void DoSomthing()
        {
            
        }
    }
    public class Program
    {
        static void Main(string[] args)
        {

            ArgSettings argsSettings = BindArgsSettings(Environment.GetCommandLineArgs());

            var host = Host.CreateDefaultBuilder(args)
              .ConfigureServices((context, services) =>
              {
                  var configurationRoot = context.Configuration;


                  services.Configure<ArgSettings>(
                      configurationRoot.GetSection("Defaults:Args"));

                  services.AddTransient<IService, MyService>();

              }).Build();
        }
    }

default config section in appsettings.json:

...

"Defaults": {
    "Args": {
        "Name": "John",
        "Region": "USA"
    }
}

...
like image 621
Jornia Kabakum Avatar asked Oct 17 '25 06:10

Jornia Kabakum


1 Answers

First, when you use IOptions.. you have to use the ".Value"

below code is from : https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0

private readonly PositionOptions _options;

public Test2Model(IOptions<PositionOptions> options)
{
    _options = options.Value;
}

Or more generically (less ambiguous):

public class MyCoolClass
{
private readonly MyWhateverSettings _settings;

public MyCoolClass(IOptions<MyWhateverSettings> options)
{
    _settings = options.Value;
}

(back to your code)

While I see this code above:

BindArgsSettings(Environment.GetCommandLineArgs());

I don't see what you are doing with the "result of that call".

Ok, here is a Unmodified Microsoft Sample: (from https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0 )

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

(the above being used as a sanity check)

What I think you want:

/* has the possibility to be null, if the user "passes" on customizing it */
ArgSettings myArgsSettings = BindArgsSettings(Environment.GetCommandLineArgs());


if (null == myArgsSettings)
{
    /* user "passed up" doing it manually, so go get the "Defaults" */
    myArgsSettings = configurationRoot.GetSection("Defaults:Args");
}

/* now DI inject */

builder.Services.Configure<ArgSettings>(myArgsSettings);

Aka, you are doing something with the result (from 'BindArgsSettings(Environment.GetCommandLineArgs()') .. aka, what has hydrated the 'myArgsSettings' variable. (the first hydration of myArgsSettings that is)

Or below is a "less ambiguous" implementation:

/* has the possibility to be null, if the user "passes" on customizing it */
ArgSettings userProvidedArgsSettings = BindArgsSettings(Environment.GetCommandLineArgs());


ArgSettings fromJsonArgSettings = null;

if (null == userProvidedArgsSettings)
{
    /* user "passed up" doing it manually, so go get the "Defaults" */
    fromJsonArgSettings = configurationRoot.GetSection("Defaults:Args");
}

if (null == userProvidedArgsSettings && null == fromJsonArgSettings)
{
    throw new ArgumentNullException("Guh, Both UserProvider AND fromJson are null.", (Exception) null);
} 


/* now DI inject */

if (null != userProvidedArgsSettings)
{
builder.Services.Configure<ArgSettings>(userProvidedArgsSettings);
}

if (null != fromJsonArgSettings)
{
    builder.Services.Configure<ArgSettings>(fromJsonArgSettings);
}
like image 126
granadaCoder Avatar answered Oct 20 '25 11:10

granadaCoder